【问题标题】:Laravel 5.4 Set All Authentication Routes Except Logout Route - Using Custom Logout Route/ControllerLaravel 5.4 设置除注销路由以外的所有身份验证路由 - 使用自定义注销路由/控制器
【发布时间】:2018-02-09 23:45:41
【问题描述】:

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

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

Auth::routes();

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

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

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

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

对不起,如果这是一个重复的条目,我在过去的一个小时里一直在使用搜索栏,但没有人回答我的问题。

编辑:我对资源路由进行了更多研究,并意识到它不是我链接到路由上的方法,而是具有键值对的数组。请参阅下面的代码(摘自 laravel 文档)。

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

【问题讨论】:

    标签: php laravel authentication laravel-5 routes


    【解决方案1】:

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

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

    长话短说...你不能。如果你想使用Auth::routes()速记,那么它是一种all-or-nothing类型的命令。 You can view the actual source code behind that command here for Laravel v5.5(尽管我相信它自 5.2 版以来没有改变),查看速记命令背后的实际代码,您可以看到它不接受任何参数,例如您对其他路由辅助命令所期望的 ['except' => 'logout'] 数组在拉拉维尔。这里没有隐藏的、未记录的秘密可以让这个命令做任何独特的事情,通过检查源代码我们可以看到它没有设置做任何事情,除了返回一个预设的路由列表。

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

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

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

    // 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 请求访问注销命令(而不是 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) 第二种选择是在您的 Auth::routes() 速记之外添加一个 GET 版本。

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

    这个选项的结果代码是这样的:

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

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

    到此,进入Auth::routes() 速记命令世界的漫长曲折之旅。

    【讨论】:

    • 很好的答案,感谢您抽出宝贵时间回答这个问题。似乎 laravel 的创建者会这样做,以便您可以将 routes() 方法传递给一个数组并在其中定义 except 键,就像在资源路由中一样。不幸的是,我认为这被忽略了。这种类型的功能对于那些制作具有 2、5 或 10 种用户类型的超级多身份验证应用程序的人来说非常有用,这样所有的注销命令都可以放在一个 LogoutController 中。 le sigh 我不认为添加这个功能会那么难,也许我们可以合作并提出一个拉取请求?推特上的 HMU!
    【解决方案2】:

    在 Laravel 6.x 中,一些身份验证路由发生了变化。可以使用下面这行代码排除注册路由。

    Auth::routes(['register' => false]);

    但是,由于您要求注册路由仍然保持不变,因此您必须按照回答此问题的其他人所做的操作,并手动定义所有路由。但是,他们的答案尚未更新到当前版本的 Laravel。所以这里是从 6.x 版本开始的所有路由的更新列表。

    // User Authentication Routes
    Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
    Route::post('login', 'Auth\LoginController@login');
    Route::post('logout', 'Auth\LoginController@logout')->name('logout');
    
    // User Registration Routes
    Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
    Route::post('register', 'Auth\RegisterController@register');
    
    // User 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')->name('password.update');
    
    // User Verification Routes
    Route::get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
    Route::get('email/verify/{id}/{hash}', 'Auth\VerificationController@verify')->name('verification.verify');
    Route::post('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
    

    【讨论】:

    • 此信息不应该只是附加到您的原始帖子的编辑/更新,而不是您自己问题的选定答案吗?尤其是因为您已经有了一个更详细、更彻底并获得支持的社区响应?此响应实际上更像是更新而不是实际答案。
    猜你喜欢
    • 1970-01-01
    • 2021-09-09
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 2011-09-05
    相关资源
    最近更新 更多