【发布时间】:2021-05-19 23:15:10
【问题描述】:
首先,我已经在 StackOverflow 和其他网站上阅读过其他类似的问题。在将我重定向到其他已解决的问题之前,请阅读我要说的内容:)
我正在使用 Laravel 官方文档中详述的护照,以便我的 js 应用程序可以使用我的 Laravel API,使用由 CreateFreshApiToken 类创建的 cookie 中设置的访问令牌。我没有问题,即使使用它来访问 GraphQL 查询(我不得不将 apollo-client 更改为 Axios 来实现这一点。由于我不明白的原因,apollo 没有发送 cookie)。
问题是我运行 composer install 并且 Laravel 从 6.x 更新到 8,所以一切都坏了。经过多次尝试解决后,我决定回滚到 Laravel 6.x,一切都恢复正常,除了 CreateFreshApiToken 类...
现在,Axios 继续使用 cookie,但后端没有按预期响应,因为它的行为就像它没有收到任何 cookie,因此中间件响应是“未经身份验证”。
如果某些依赖项没有很好地回滚到原始状态,我可以很明显地猜测它们与此有关。不管这个假设是否正确,我仍然认为解决方案是对我的依赖项的当前状态采用一些代码。
这个问题与 Passport 本身无关,因为如果我使用获得的 access_token 显式测试一个请求,它工作得很好。
编辑:我成功在服务器端检查了 cookie 是否包含在请求中。
项目信息
Laravel 框架 6.20.27 php 7.3.4 节点 v14.17.0
相关代码:
内核.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();
}
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');
}
}
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"
},
将非常感谢您的 cmets。 问候。
【问题讨论】:
标签: php laravel cookies laravel-passport