Laravel中如何判断当前请求对应的认证Guard?多Guard登录场景
嘿,这个场景我之前也碰到过,当同一个浏览器里同时登录了普通用户和管理员时,确实会出现两个check()都返回true的情况——因为Laravel的每个Guard是独立维护登录状态的,Auth::check()默认检查的是配置里的默认Guard(比如你的web),而Auth::guard('admin')->check()专门检查admin Guard,两者互不影响。
要判断当前请求到底对应哪个Guard,可以试试这几种实用方法:
方法一:利用Auth facade获取当前默认Guard
当你在路由中使用了auth:admin或者auth:web这类带Guard参数的中间件时,Laravel会自动调用Auth::shouldUse($guardName)来设置当前请求的默认Guard。这时候直接用下面的代码就能拿到当前Guard的名称:
// 方式1:直接获取当前默认Guard的驱动名称 $currentGuard = Auth::getDefaultDriver(); // 方式2:通过Guard实例获取名称 $currentGuard = Auth::guard()->getName();
比如如果当前请求是管理员路由(用了auth:admin中间件),$currentGuard就会返回admin;普通用户路由则返回web。
方法二:检查路由的中间件配置
如果你的路由明确指定了对应的Auth中间件,也可以直接从路由的中间件列表里提取Guard名称:
$route = request()->route(); $currentGuard = null; foreach ($route->middleware() as $middleware) { // 匹配auth:xxx格式的中间件 if (strpos($middleware, 'auth:') === 0) { $currentGuard = substr($middleware, 5); break; } } // 此时$currentGuard就是当前请求对应的Guard名称(如果路由配置了的话)
方法三:通过用户模型类反向判断
因为你的两个Guard对应不同的用户Provider(users对应普通用户模型,admins对应管理员模型),所以也可以通过当前登录用户的模型类来反向推导Guard:
$user = Auth::user(); if ($user instanceof \App\Models\User) { // 当前是web Guard对应的普通用户 $currentGuard = 'web'; } elseif ($user instanceof \App\Models\Admin) { // 当前是admin Guard对应的管理员 $currentGuard = 'admin'; }
这个方法适合你需要同时根据用户类型做逻辑区分的场景,顺便也能拿到Guard信息。
补充说明
为什么两个check()都返回true?因为Laravel的每个Guard都会在Session中存储独立的登录状态(比如web Guard的Session键是login_web_xxxxxx,admin的是login_admin_xxxxxx),所以当你同时登录两个Guard时,两者的登录状态都会被保留,各自的check()自然都返回true。
内容的提问来源于stack exchange,提问作者Naveed

