72

I am using Laravel 5.4 and trying to implement authentication system. I used php artisan command make:auth to setup it. I edited the views according to my layout. Now, when I am trying to logout it throwing me this error

NotFoundHttpException in RouteCollection.php line 161:

could any one help me how to logout?

Y.EzzEldin
  • 801
  • 1
  • 8
  • 11

14 Answers14

190

In your web.php (routes):

add:

Route::get('logout', '\App\Http\Controllers\Auth\LoginController@logout');

In your LoginController.php

add:

public function logout(Request $request) {
  Auth::logout();
  return redirect('/login');
}

Also, in the top of LoginController.php, after namespace

add:

use Auth;

Now, you are able to logout using yourdomain.com/logout URL or if you have created logout button, add href to /logout

BILL WAGNER
  • 155
  • 3
  • 13
Tauras
  • 3,846
  • 3
  • 21
  • 36
68

Well even if what suggest by @Tauras just works I don't think it's the correct way to deal with this.

You said you have run php artisan make:auth which should have also inserted Auth::routes(); in your routes/web.php routing files. Which comes with default logout route already defined and is named logout.

You can see it here on GitHub, but I will also report the code here for simplicity:

    /**
     * Register the typical authentication routes for an application.
     *
     * @return void
     */
    public function auth()
    {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');
        // Registration Routes...
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');
        // Password Reset Routes...
        $this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
        $this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
        $this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
        $this->post('password/reset', 'Auth\ResetPasswordController@reset');
    }

Then again please note that logout requires POST as HTTP request method. There are many valid reason behind this, but just to mention one very important is that in this way you can prevent cross-site request forgery.

So according to what I have just pointed out a correct way to implement this could be just this:

<a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('frm-logout').submit();">
    Logout
</a>    
<form id="frm-logout" action="{{ route('logout') }}" method="POST" style="display: none;">
    {{ csrf_field() }}
</form>

Finally note that I have inserted laravel out of the box ready function {{ csrf_field() }}!

Sid
  • 14,176
  • 7
  • 40
  • 48
23

You can use the following in your controller:

return redirect('login')->with(Auth::logout());
Usama Munir
  • 589
  • 9
  • 11
  • This should be an accepted answer. Works like a charm! – willbeeler Aug 28 '18 at 19:31
  • 1
    This makes no sense. `with()` is for flashing data to the session and takes a string or array. Why would you put `Auth::logout()` there? It doesn't even return anything, as its return type is void. – halloei Apr 28 '21 at 16:17
  • 1
    This still works with Laravel >8 like charm – Lefty May 31 '22 at 10:15
15

Best way for Laravel 5.8

100% worked

Add this function inside your Auth\LoginController.php

use Illuminate\Http\Request;

And also add this

public function logout(Request $request)
{
    $this->guard()->logout();

    $request->session()->invalidate();

    return $this->loggedOut($request) ?: redirect('/login');
}
  • How to prevent from using "Back" function from the browser, I still can accessed the last page but cannot operate the fitures. I only get this error `Trying to get property 'name' of non-object `. I also using laravel 5.8. – Kris Jul 11 '20 at 08:11
  • note that you need to import Illuminate\Foundation\Auth\AuthenticatesUsers – Zoren Konte Mar 16 '21 at 07:42
  • @Kris for this you need to pass no-cache to response for all auth routes. The back button works with cache. So once you click back on browser it pops from cache. – Insane Developer Jun 03 '21 at 13:31
10

here is another way to do it by calling Auth::logout() in route

Route::get('/logout', function(){
   Auth::logout();
   return Redirect::to('login');
});
Somwang Souksavatd
  • 4,947
  • 32
  • 30
6

I recommend you stick with Laravel auth routes in web.php: Auth::routes()

It will create the following route:

POST | logout | App\Http\Controllers\Auth\LoginController@logout

You will need to logout using a POST form. This way you will also need the CSRF token which is recommended.

<form method="POST" action="{{ route('logout') }}">
  @csrf
  <button type="submit">Logout</button>
</form>
Jonathan Roy
  • 461
  • 5
  • 4
5

In Laravel 6.2

Add the following route to : web.php

Route::post('logout', 'Auth\LoginController@logout')->name('logout');

Using Achor tag with logout using a POST form. This way you will also need the CSRF token.

 <a class="log-out-btn" href="#" onclick="event.preventDefault();document.getElementById('logout-form').submit();"> Logout </a>

 <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
          {{ csrf_field() }}
  </form>
Ghanshyam Nakiya
  • 1,602
  • 17
  • 24
3

In 5.5

adding

Route::get('logout', 'Auth\LoginController@logout');

to my routes file works fine.

Beefjeff
  • 371
  • 4
  • 12
  • don't do this, see the response of Sid. Other websites can log users out while redirecting someone to domain.com/logout – kendepelchin Feb 21 '18 at 19:34
2

I know this question was asked for old version of laravel. I want to share my solution for Laravel 8.65 version. In AuthenticatedSessionControler update destroy function like this.

public function destroy(Request $request)
{
    Auth::guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    return redirect('/admin');
}

update your last line from return redirect('/') to return redirect('/admin');

msayubi76
  • 1,446
  • 1
  • 12
  • 18
1

It's better and safer to add to your LoginController.php the following code, that runs only after the standard logout:

use AuthenticatesUsers;

protected function loggedOut(Request $request)
    {
        return redirect('/new/redirect/you/want');
    }
user3881450
  • 76
  • 1
  • 3
0

If you used the auth scaffolding in 5.5 simply direct your href to:

{{ route('logout') }}

There is no need to alter any routes or controllers.

rashedcs
  • 3,588
  • 2
  • 39
  • 40
  • doesn't work when I try it. Laravel throw an error `Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException No message` – Bariq Dharmawan Mar 20 '18 at 04:32
  • 1
    @BariqDharmawan It's because the logout route is a POST route, which means you have to put it in a form. Ex., method="POST" action="{{ route('logout') }}" – willbeeler Aug 28 '18 at 19:30
0

In Laravel 9

go to routes directory open web.php and write logout route:

use App\Http\Controllers\Auth\LoginController;
Route::get('logout', [LoginController::class,'logout']);

From blade add logout URL

<a class="dropdown-item" href={{route('logout')}}>Logout</a>

Notice

logout function will redirect to home page /

If you want to redirect to login page you should override on logout function in App\Http\Controllers\Auth\LoginController.php

public function logout(){  
   return redirect('login')->with(Auth::logout());
}
Eng_Farghly
  • 1,987
  • 1
  • 23
  • 34
0

Just in case someone is interested on this topic for Laravel 8 or 9.

As you can read on the Laravel documentation on https://laravel.com/docs/9.x/authentication#logging-out

In addition to Auth::logout(), you will need to invalidate the user's session and regenerate their CSRF token:

public function logout(Request $request)
{
    Auth::logout();
 
    $request->session()->invalidate();
 
    $request->session()->regenerateToken();
 
    return redirect('/');
}
Luis Rodriguez
  • 355
  • 3
  • 7
-1

if you are looking to do it via code on specific conditions, here is the solution worked for me. I have used in middleware to block certain users: these lines from below is the actual code to logout:

$auth = new LoginController();
$auth->logout($request);

Complete File:

namespace App\Http\Middleware;
use Closure;
use Auth;
use App\Http\Controllers\Auth\LoginController;
class ExcludeCustomers{
    public function handle($request, Closure $next){
        $user = Auth::guard()->user();
        if( $user->role == 3 ) {
            $auth = new LoginController();
            $auth->logout($request);
            header("Location: https://google.com");
            die();
        } 
        return $next($request);
    }
}