ruchern.chong's avatar

Laravel 5.3 Logout MethodNotAllowed

I've upgraded from Laravel 5.2 to Laravel 5.3. Since the changes from GET to POST, I am getting an error for MethodNotAllowed. I was using the Authentication Scaffolding previously in 5.2 for my authentication part of the app.

Any help here?

Edit: Got it to work.

0 likes
12 replies
nate.a.johnson's avatar

Alternatively you can hack it back to how it used to work by adding this route:

Route::get('logout', '\App\Http\Controllers\Auth\LoginController@logout');
13 likes
lchogan's avatar

Is there a reason this was changed to POST?

2 likes
mustafiz89's avatar

Just use this on your route file ..... Route::get('/logout' , 'Auth\LoginController@logout');

onamfc's avatar

Here's a way to use the logout as intended. Since the logout route was change to a POST method, you must POST the logout. To do so, use

<li>
    <a href="{{ url('/logout') }}" 
         onclick="event.preventDefault();
         document.getElementById('logout-form').submit();">
          Logout
    </a>
     <form id="logout-form" 
            action="{{ url('/logout') }}" 
        method="POST" 
        style="display: none;">
                    {{ csrf_field() }}
      </form>
</li>
13 likes
ruchern.chong's avatar
ruchern.chong
OP
Best Answer
Level 11

The best way to implement this is:

<a href="{{ route('logout') }}" 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>

Since Auth::routes() already comes with name routes, we are using the route() method for this case.

style="display: none;" can be left out as form usually do not show up if there are no visible input fields.

12 likes
juansebas257's avatar

Hello, I have a question: why the href attrib in the a tag is necessary, if the onclick method prevent it and then submit the form?

1 like
wturrell's avatar

@juansebas257 without an href attribute many browsers won't underline the link. Also allows a user to hover over the link and see 'logout' in the status bar and provide some reassurance about what will happen.

Breaks without javascript of course...

1 like
mpmurph's avatar

I started with @ruchern's solution but found it didn't work for me on touch screen devices so had to adapt it a bit, creating an event handler like so:

var submitLogoutForm = function(event) {

    event.stopImmediatePropagation();
    event.preventDefault();
    document.getElementById('logout-form').submit();

};

Then, I assigned the class 'logout-trigger' to the parent nodes of all logout links and attached the event handler with jQuery like so:

$('.logout-trigger').on('click touchstart', submitLogoutForm);

The touchstart event seems to be necessary to capturing what amounts to a click action on mobile devices (or at least on the iPhone). That said, I haven't been able to test it across all/most devices but hopefully it will help others who come on this thread.

Please or to participate in this conversation.