laravel 使用 auth:admin 中间件后, 会把 Auth->defaultDriver 设置为 admin

问题出现背景: 使用非默认的 auth guard 时发现 Auth::user() 和 Auth::guard(‘admin’) 的结果竟然是一样的

原因: 路由中使用了 auth:admin 中间件后, 会自动把当前 driver 设置为对应的admin

配置 config/auth.php

'providers' => [
  'users' => [
  'driver' => 'eloquent',
  'model' => App\Models\User::class,
 ],

 // 'users' => [
 //     'driver' => 'database', 
 //     'table' => 'users', 
 // ],

'admins' => [
  'driver' => 'eloquent', // 这里要配置成 eloquent 而不是 database
  'model' => App\Models\Admin::class, // 这里要配置成 model, 而不是 tableName
 ],// 如果按 database + tablename 方式来使用 auth, 不能完全达到 User 一样的效果 
],

编写 Models/Admin.php

// 让 Admin.php 继承 User Model, 从而可以使用 Authenticate Trait 等
class Admin extends User 
{
  ...
}

编写 web.php 路由

Route::get('admin', [AdminsController::class, 'index'])->middleware('auth:admin');

编写 AdminsController.php

class AdminsController extends Controller
{
  public function index () {
    Auth::guard('admin')->user(); // 需要在 auth.php 中设置为 eloquent + model, 如果是 database + table, 这里会返回一个 GenericUser 对象, 而不是 Admin 模型对象, 也就不能使用之后的 $this->authorize 进行权限校验
    Auth::user(); // 等同于上一条, 因为 route-middleware 中会自动设置 defaultDriver 为 guard(admin)
    $this->authorize('create', Post::class);  // 那么这里就可以直接使用 $this->authorize 进行 policy 授权.
  }
}

参考: 源码 Illuminate\Auth\Middleware\Authenticate 中设置 driver 的部分

handle -> authenticate -> shouldUse

.
.
.
    public function handle($request, Closure $next, ...$guards)
    {
        $this->authenticate($request, $guards);
        return $next($request);
    }

    /**
     * Determine if the user is logged in to any of the given guards.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $guards
     * @return void
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    protected function authenticate($request, array $guards)
    {
        if (empty($guards)) {
            $guards = [null];
        }

        foreach ($guards as $guard) {
            if ($this->auth->guard($guard)->check()) {
                return $this->auth->shouldUse($guard);
            }
        }

        $this->unauthenticated($request, $guards);
    }

    public function shouldUse($name)
    {
       $name = $name ?: $this->getDefaultDriver();
       $this->setDefaultDriver($name);
       $this->userResolver = function ($name = null) {
       return $this->guard($name)->user();
    };
.
.
.
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2

你是不是用了 passport?然后前后端都分离了?

3年前 评论
beatles (楼主) 3年前

有多个端jwt生成的时候去 生成和和取值要带上识别名称直接取很容易冲突

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!