Robinson, thanks for reaching out to me on Twitter for help on this answer. I actually think this is a great question and hope this question finds its way up Google ranks for future devs to find and maybe spark a little discussion in the community.
How can I prevent the logout route from being produced with Auth::routes()
command?
Long story short... you can't. If you want to use the Auth::routes()
shorthand, then it is an all-or-nothing type of command. You can view the actual source code behind that command here for Laravel v5.5 (although it hasnt changed since version 5.2 I believe), and viewing the actual code behind the shorthand command you can see that it accepts no parameters such as the ['except' => 'logout']
array that you have come to expect with other route helper commands in Laravel. There are no hidden, undocumented secrets here to make this command do anything unique, by inspecting the source code we can see that it isn't setup to do anything other than return a pre-set list of routes.
It literally just outputs a set of routes with no logic (decision making) at all. This command is just a shorthand method that prevents you from having to write all those routes yourself.
With that being said, there is no reason that you HAVE to use this shorthand. You can manually make all of these routes yourself. Look at the source code I linked above or run php artisan r:l
(another shorthand for route:list
for any noobs reading this) and copy the same output into your routes file. This allows you to skip over or modify any routes to your liking.
This is what the routes would look like if you want to add them without the shorthand command. Make sure to delete that command and paste these in instead. Whichever commands you want to delete or modify can easily be done so like any other route. I took this from the Laravel source code, so it is 100% EXACTLY the same as the shorthand command creates, including the order of the routes (and technically the comments too).
Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController@login');
Route::post('logout', 'Auth\LoginController@logout')->name('logout');
Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\RegisterController@register');
Route::get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
Route::post('password/reset', 'Auth\ResetPasswordController@reset');
So if you wanted to copy this code block and add it to your routes file, it would give you the exact same results (and does the same thing behind the scenes) as the shorthand Auth::routes()
command does. Now you can customize or remove any of the commands that you want.
How do I change the logout route into a GET
route?
So now that we discussed how you work with authentication scaffolding routes, lets answer the meat and potatoes behind your question. You are looking to make the logout command accessible via a GET
request (as opposed to a POST
request which is how Laravel sets it up by default.
Easy enough, there are two ways to do this:
1) Copy all the routes and change the logout route to a GET
request
This is easy enough, delete the Auth::routes()
shorthand and then copy the routes I posted above and paste it into your routes file in the same location that your Auth::routes()
used to be. Then on the third route of our new authentication routes, we find the logout one. Simply change it from Route::post()
to Route::get()
and leave everything else the same.
Your routes file will look like this now:
You could just copy and paste this below and go about your business now.
Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController@login');
Route::get('logout', 'Auth\LoginController@logout')->name('logout');
Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\RegisterController@register');
Route::get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
Route::post('password/reset', 'Auth\ResetPasswordController@reset');
2) The second option is to add a GET
version in addition to your Auth::routes()
shorthand.
This would ultimately make the logout route accessible via both a GET
and a POST
request. They both link to the same method, so they do the same thing and work in the same way and now you can logout as either a POST
or GET
request.
The resulting code of this option would be this:
Auth::routes();
Route::get('logout', 'Auth\LoginController@logout');
Note that I omitted the name from the second line. It is already named thanks to the Auth::routes()
command. So you don't need to name it again. The logout
name will still work though. So you can still use <a href="{{ route('logout') }}">Logout</a>
in your blade files and the route name will work regardless of whether you are using it as a GET
or POST
request.
So there you go, a long winding journey into the world of Auth::routes()
shorthand command.