laravel 使用 auth:admin 中介軟體後, 會把 Auth->defaultDriver 設定為 admin

beatles發表於2021-01-12

原因: 路由中使用了 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 協議》,轉載必須註明作者和本文連結

相關文章