已解决 - Laravel Passport - CreateFreshApiToken 未被 auth:api 中间件识别

SOLVED - Laravel Passport - CreateFreshApiToken is not being recognized by auth:api middleware

首先,我已经在 Whosebug 和其他网站上阅读过其他类似问题。在将我重定向到其他已解决的问题之前,请先阅读我要说的内容:)

我正在使用 Laravel 官方文档中详述的护照,这样我的 js 应用程序就可以使用我的 Laravel API 使用我创建的 cookie 中设置的访问令牌CreateFreshApiToken class。我没有问题,甚至使用它来访问 GraphQL 查询(我不得不将 apollo-client 更改为 Axios 以实现此目的。由于我不明白的原因,apollo 没有发送 cookie)。

问题是我 运行 作曲家安装和 Laravel 从 6.x 更新到 8,所以一切都坏了。经过多次尝试解决后,我决定回滚到 Laravel 6.x 并且一切都再次运行,除了 CreateFreshApiToken class...

现在,Axios 继续使用 cookie,但后端没有按预期响应,因为它的行为就像没有收到任何 cookie,因此中间件响应是 'unauthenticated'。

我可以直观地猜测,如果某些依赖项没有很好地回滚到其原始状态,则与此有关。不管这个假设是否正确,我仍然认为解决方案是对我的依赖项的当前状态采用一些代码。

这个问题与 Passport 本身无关,因为如果我使用获得的 access_token 显式测试请求,它运行良好。

编辑:我在服务器端成功检查了请求中包含的 cookie。

项目信息

Laravel 框架 6.20.27 php7.3.4 节点 v14.17.0

相关代码:

Kernel.php

protected $middleware = [
    \App\Http\Middleware\TrustProxies::class,
    \App\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ]
];

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    'checkRole' => \App\Http\Middleware\CheckRole::class    //custom middleware
];

/**
 * The priority-sorted list of middleware.
 *
 * This forces non-global middleware to always be in the given order.
 *
 * @var array
 */
protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\Authenticate::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

User.php

use SoftDeletes, SoftCascadeTrait, Notifiable, HasApiTokens;

Auth.php

'defaults' => [
    'guard' => 'web',
    'passwords' => 'users',
],

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ]
],

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

AuthServiceProvider

public function boot() {
    $this->registerPolicies();
    Passport::routes();
}

路由服务提供商

public function map() {
    $this->mapApiRoutes();
    $this->mapWebRoutes();
    //
}

protected function mapWebRoutes() {
    Route::middleware('web')
        ->namespace($this->namespace)
        ->group(base_path('routes/web.php'));
}

protected function mapApiRoutes() {
    Route::prefix('api')
        ->middleware('api')
        ->namespace($this->namespace)
        ->group(base_path('routes/api.php'));
}

登录控制器

public function handleFacebookCallback() {
    try {
        $user = Socialite::driver('facebook')->stateless()->fields(['first_name', 'last_name'])->user();

        $attributes = [
            'names' => $user->user['first_name'],
            'lastname' => $user->user['last_name'],
            'email' => $user->email,
            'facebook_id' => $user->id,
            'photo_uri' => $user->getAvatar()
        ];

        $user = User::where('facebook_id', $user->id)->first();

        if ($user) {
            // do things
        } else {
            $user = User::create($attributes);
            $user->roles()->attach(10);
        }
        
        foreach ($user->tokens as $token)
            $token->revoke();

        $this->guard()->login($user); //web login

        $token = Auth::user()->createToken('API')->accessToken; //Passport access token creation
        //shouldn't matter if token is sent or not to the view
        return View::make('welcome')->with('token', $token); 
    }
    catch(\GuzzleHttp\Exception\ClientException $e) {
        return redirect('auth/facebook');
    }
}

composer.json

"require": {
    "php": "^7.2",
    "askedio/laravel-soft-cascade": "^6.0",
    "doctrine/dbal": "^2.10",
    "fideloper/proxy": "^4.0",
    "laravel/framework": "^6.2",
    "laravel/passport": "^8.2",
    "laravel/socialite": "^4.3",
    "laravel/tinker": "^1.0",
    "laravel/ui": "1.0",
    "league/flysystem-aws-s3-v3": "^1.0",
    "rebing/graphql-laravel": "^3.1",
    "symfony/cache": "^4.2",
    "symfony/config": "^4.2",
    "symfony/console": "^4.2"
},

非常感谢您的评论。 你好。

最后,这个问题解决了更新护照到9.x