Laravel 5.4设置除注销路由之外的所有身份验证路由 - 使用自定义注销路由/控制器

时间:2017-08-31 23:08:06

标签: php laravel authentication laravel-5 routes

所以出于某种原因,我以为我之前遇到过这个问题的答案,但对于我的生活,我无法通过Google或StackOverflow再次找到答案。这可能只是一个橡皮鸭问题而且我很抱歉,如果是的话,但我希望这个问题在某一天会对同一个问题有所帮助。

让我们假设我们从Laravel 5.4的全新安装开始。我在终端中运行php artisan make:auth命令,它为我设置了身份验证脚手架。现在在我的/routes/web.php文件中,我看到以下行:

Auth::routes();

哪个很棒,路由列表中列出了所有认证路由,包括定义的注销路由。 (键入php artisan r:l进行仔细检查)现在我想使用自定义Logout Controller为用户设置自定义注销路由。现在,我认为有一种方法可以链接到一组名为'except()'的资源路由,但就我而言,我在文档中找不到有关此方法的任何信息。我不知道这种方法是否存在,更不用说知道传递什么了。

我假设Auth::routes()代可以像资源路径一样使用except方法,但我不完全确定如何实现它?

所以问题很简单。如何包括除注销路由之外的所有身份验证路由,然后我将使用以下行定义注销路由。

Route::get('logout', 'LogoutController@userLogout')->name('logout');

很抱歉,如果这是一个重复的条目,我在过去的一小时内使用了搜索栏,没有回答我的问题。

编辑:我对资源路由做了更多研究,并意识到它不是我链接到路由的方法,而是一个带有键值对的数组。请参阅下面的代码(从laravel docs中删除)。

Route::resource('photo', 'PhotoController', ['except' => [
    'create', 'store', 'update', 'destroy'
]]);

但是当我将数组传递给routes()方法时(参见下面的代码),注销路径仍然在路由列表中。但是,php artisan r:l命令没有引发任何错误。

// User Authentication Routes
Auth::routes(['except' => 'logout']);
编辑:经过大量挖掘后,似乎无法实现此类功能。我已向laravel / framework github repo提交了一个问题,要求在5.5中添加该功能。

Exclude route from Laravel authentication

https://github.com/laravel/framework/issues/20904

1 个答案:

答案 0 :(得分:11)

罗宾逊,感谢reaching out to me on Twitter对此答案的帮助。我实际上认为这是一个很好的问题,并希望这个问题能够找到未来开发人员的Google排名,并在社区中引发一些讨论。

如何使用Auth::routes()命令阻止注销路由?

长话短说...... 你不能。如果你想使用Auth::routes()速记,那么它就是全有或无 em>命令类型。 You can view the actual source code behind that command here for Laravel v5.5(虽然自5.2版以来它没有改变),并查看速记命令背后的实际代码,您可以看到它不接受任何参数,例如您期望的['except' => 'logout']数组Laravel中的其他路由助手命令。这里没有任何隐藏的,未记录的秘密来使这个命令做任何独特的事情,通过检查源代码,我们可以看到除了返回预先设置的路由列表之外,它不能进行任何其他操作。

它实际上只输出一组没有逻辑(决策)的路线。此命令只是一种速记方法,可以防止您自己编写所有这些路径。

话虽如此,没有理由你必须使用这种速记。您可以自己手动制作所有这些路线。查看我上面链接的源代码或运行php artisan r:lroute:list的另一个简写,用于阅读此内容的任何新手)并将相同的输出复制到您的路径文件中。这允许您根据自己的喜好跳过或修改任何路线。

如果您想在没有速记命令的情况下添加路线,这就是路线的样子。确保删除该命令并将其粘贴到其中。无论您想要删除或修改哪个命令都可以像其他任何路径一样轻松完成。我从Laravel源代码中获取了这个,因此它与速记命令创建的100%完全相同,包括路由的顺序(以及技术上的注释)。

// Authentication Routes...
Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController@login');
Route::post('logout', 'Auth\LoginController@logout')->name('logout');

// Registration Routes...
Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\RegisterController@register');

// Password Reset Routes...
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');

因此,如果您想复制此代码块并将其添加到路径文件中,它将为您提供与简写Auth::routes()命令完全相同的结果(并在幕后执行相同的操作)。现在,您可以自定义或删除任何所需的命令。

如何将注销路线更改为GET路线?

现在我们讨论了如何使用身份验证脚手架路由,让我们回答你问题背后的肉和土豆。您希望通过GET请求访问logout命令(而不是POST请求,这是Laravel默认设置的方式。

很简单,有两种方法可以做到这一点:

1)复制所有路线并将注销路线更改为GET请求

这很简单,删除Auth::routes()简写,然后复制我在上面发布的路线,并将其粘贴到路径文件中,与您Auth::routes()过去的位置相同。然后在新的身份验证路由的第三条路径上,我们找到了注销路由。只需将其从Route::post()更改为Route::get(),并将其他所有内容保持不变。

您的路线文件现在将如下所示: 您可以在下面复制并粘贴此内容,然后立即开展业务。

// Authentication Routes...
Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController@login');
Route::get('logout', 'Auth\LoginController@logout')->name('logout');

// Registration Routes...
Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\RegisterController@register');

// Password Reset Routes...
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)第二个选项是在GET简写之外添加Auth::routes()版本。

这最终会通过GETPOST请求访问注销路线。它们都链接到相同的方法,因此它们执行相同的操作并以相同的方式工作,现在您可以注销为POSTGET请求。

此选项的结果代码如下:

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

请注意,我从第二行省略了名称。由于Auth::routes()命令,它已经命名了。所以你不需要再次命名。 logout名称仍然可以使用。因此,您仍然可以在刀片文件中使用<a href="{{ route('logout') }}">Logout</a>,无论您是将其用作GET还是POST请求,路由名称都可以使用。

所以你去了Auth::routes()速记命令的世界。