繁体   English   中英

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

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

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

I was using passport as detailed in the official documentation of Laravel so that my js app could use my Laravel API using the access token set in the cookie created by the CreateFreshApiToken class. 我没有问题,即使使用它来访问 GraphQL 查询(我必须将 apollo-client 更改为 Axios 来实现这一点。出于我不明白的原因,apollo 没有发送 cookie)。

问题是我运行了 composer install 和 Laravel 从 6.x 更新到 8,所以一切都坏了。 经过多次尝试解决它,我决定回滚到 Laravel 6.x 并且一切都恢复正常,除了 CreateFreshApiToken class ...

现在,Axios 继续使用 cookie,但后端没有按预期响应,因为它的行为就像它没有收到任何 cookie,因此中间件响应是“未经身份验证”。

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

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

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

项目信息

Laravel 框架 6.20.27 php 7.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,
];

用户.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,
    ],
],

身份验证服务提供者

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

RouteServiceProvider

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');
    }
}

作曲家.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 解决了这个问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM