已解决 - 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
首先,我已经在 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