Laravel 路由组和中间件
Posted
技术标签:
【中文标题】Laravel 路由组和中间件【英文标题】:Laravel route group and middlewares 【发布时间】:2022-01-11 14:38:18 【问题描述】:我正在与可以验证状态(已验证电子邮件)的用户一起开发一个 laravel 项目。
另一方面,用户可以拥有由“订阅”中间件验证的订阅。
所以我有几组路线,包括 2 组,其中唯一的区别是是否存在订阅
第一组:
Route::group(['middleware' => ["auth:sanctum", "verified"]], function ()
第 2 组
Route::group(['middleware' => ["auth:sanctum", "verified", "subscriptions"]], function ()
我的问题是关于 laravel 用于这些组中的路线的顺序。例如,如果用户满足第一组的所有中间件,laravel 会测试第二组的中间件吗? 已验证的用户是否有机会进入第二组订阅路线?
反之,如果用户没有订阅,则不会通过订阅中间件。但我的印象是用户被订阅中间件重定向失败,而 laravel 可以在没有这个中间件的组中找到正确的路由(组 1)
我想要的是它只是测试是否存在订阅,如果找不到它会在 group1 中查找路由。
代码中组的顺序对处理有影响吗?
谢谢。
编辑:
Route::group(['middleware' => ["auth:sanctum", "verified", ]], function ()
Route::get("/new", function ()
// redirect to payment
)->name("new-payment");
Route::group(['middleware' => ["auth:sanctum", "verified", "subscriptions"]], function ()
Route::get("/new", function ()
return view("bourse-new");
)->name("new-abo");
它是相同的路由,但根据订阅的存在与否具有不同的行为 当订阅中间件失败时,它会重定向到“家”,但我希望 laravel 使用第一条路线
【问题讨论】:
实际路线是否不同?你能提供例子吗?您也许可以只嵌套您的组/中间件。 @Peppermintology 感谢您的关注。我想,如果用户有订阅,他可以创建一个新项目,如果没有,他会被重定向到付款。 所以你是说即使subscriptions
中间件返回false
组内的路由是可访问的?
@ManojKiranAppathurai,组内的路由无法访问,但由于“订阅”失败,它重定向到“家”,我只是希望它使用第一组的路由,一个没有这个中间件的
否 你不能将相同的 URI 添加到不同的路由
【参考方案1】:
感谢@NoobDev。
我通过将订阅测试集成到中间件来接管他的解决方案
Route::group(['middleware' => ["auth:sanctum", "verified"]], function ()
Route::get("/new", function ()
return view("bourse-new");
)->middleware("subscriptions")->name("bourse-new");
);
和订阅中间件:
public function handle(Request $request, Closure $next)
if( //logic tests)
return $next($request);
return redirect('/checkout'); //redirect to payment
这个解决方案几乎是完美的,谢谢大家
【讨论】:
【参考方案2】:我的问题是关于 laravel 在这些路线中使用的顺序 团体。例如,如果用户满足所有的中间件 第一组,laravel会测试第二组的中间件吗?
如果您点击了第一组中包含的路线,laravel 将不会检查其他路线。
做一个 用户验证有机会进入第二组路线 订阅?
如果他没有订阅,他就不能
代码中组的顺序对处理有影响吗?
是的,如果您使用相同的 uri,最后一个将覆盖前一个
Route::group(['middleware' => ["auth:sanctum", "verified", ]], function ()
Route::get("/new", function ()
// redirect to payment
)->name("new-payment");
Route::group(['middleware' => ["auth:sanctum", "verified", "subscriptions"]], function ()
Route::get("/new", function ()
return view("bourse-new");
)->name("new-abo");
试试 php artisan route:list,第二组可能会覆盖第一组
好的,谢谢,但我想要不同的行为,具体取决于存在 是否订阅
在用户模型中:
public function hasSubscribed()
//do your logic to check if has subscription
您可以使用第一个组并检查 Auth::user() 是否已订阅。像这样:
if (auth()->user()->hasSubscribed())
return view()
//or ...
【讨论】:
你是对的,有了 route: list,只会出现第二条路线。 你的解决方案太棒了,我想知道为什么我没有想到它。 没什么了不起的!顺便说一句,总是很乐意提供帮助【参考方案3】:在app/Http/Kernel.php
protected $middlewarePriority = [
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
文档: https://laravel.com/docs/8.x/middleware#sorting-middleware
【讨论】:
以上是关于Laravel 路由组和中间件的主要内容,如果未能解决你的问题,请参考以下文章