我已经开发了多个带有blade和Vue组件的传统Laravel 5.x Web应用程序,但现在我正在开发一个新的Laravel 7 SPA应用程序,其中包含React和Sanctum,并且我已经安装了UI/Auth软件包(现在是独立的(。
我可以使用我的 React/Axios 表单登录,但无法在"routes/api.php"中定义的路由中获取登录用户(使用"Auth::user(("(。但是当我在"routes/web.php"中定义调用完全相同的控制器/方法的不同路由时,我确实会得到登录的用户。
也许它与"app/Http/Kernel.php"中的中间件定义有关 - 我有:
protected $middlewareGroups = [
'web' => [
AppHttpMiddlewareEncryptCookies::class,
IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
IlluminateSessionMiddlewareStartSession::class,
// IlluminateSessionMiddlewareAuthenticateSession::class,
IlluminateViewMiddlewareShareErrorsFromSession::class,
AppHttpMiddlewareVerifyCsrfToken::class,
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
'api' => [
'throttle:60,1',
EnsureFrontendRequestsAreStateful::class,
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
];
有什么想法吗?
自从发布这篇文章以来已经有一段时间了,我不知道你是否已经找到了答案。
您可能忘记使用auth:sanctum中间件来注入当前经过身份验证的用户。
这是我唯一可以指出的关于您在代码方面提供的内容。
默认的api
中间件堆栈是无状态的。我不知道你的EnsureFrontendRequestsAreStateful::class
在这里做什么。
因此,有几种解决方案可以解决此问题:
添加与web
相同的中间件
向'api'
组添加一些额外的中间件,以便您的 cookie 能够识别您的会话(只有第一个是必需的(,就像它与'web'
中间件一起使用一样:
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
请注意,这会使您的 API 有状态(因为它现在接收会话(,这可能是不希望的。
使用内置token
防护进行身份验证
这被定义为api
身份验证防护的默认驱动程序(请参阅config/auth.php
(
(https://github.com/laravel/laravel/blob/master/config/auth.php#L45(
它检查是否存在(按此顺序(:
?api_token=xxx
查询参数api_token
请求正文参数Authorization: Bearer xxx
标头- 名为
PHP_AUTH_PW
的标头
请参阅 https://github.com/laravel/framework/blob/7.x/src/Illuminate/Auth/TokenGuard.php#L97IlluminateAuthTokenGuard::97
以了解这是如何发生的。
token
防护依赖于users
表中的api_token
列,该列根据上面列表中的项目之一进行检查。有关如何添加此列的示例迁移,请参阅 https://laravel.com/docs/6.x/api-authentication#database-preparation。
在服务提供商boot()
方法中创建自定义身份验证防护
如此处所述 https://laravel.com/docs/7.x/authentication#closure-request-guards.例如,这个使用X-Api-Key
标头对用户进行身份验证:
Auth::viaRequest('custom-token', function ($request) {
return User::where('token', $request->header('X-Api-Key')->first();
});
然后,您可以在config/auth.php
文件中分配'driver' => 'custom-token'
。
请注意,这一切都取决于IlluminateAuthAuthServiceProvider::class
,应始终在config/app.php['providers']
列表中定义。这是确保Auth::user()
函数等在代码中可用的基本服务提供程序。
因此,如果要要求对特定路由进行身份验证,则必须将'auth'
中间件(这是AppHttpMiddlewareAuthenticate::class
的简写,如appHttpKernel::$routeMiddleware
所示(添加到'api'
中间件组以进行 API 范围的身份验证,或添加到单独的路由。