cub*_*war 6 laravel angular laravel-sanctum
我有一个由 Laravel 驱动的 api,本地托管在http://tenant.api.hydrogen.local上,还有一个 Angular 9.2 SPA,在http://localhost:8100上提供服务。我最近安装了 Laravel Sanctum 进行身份验证,并按照文档中列出的 SPA 说明进行操作,但 CSRF 令牌未附加到来自 SPA 的请求,因此我收到 CSRF 令牌不匹配错误。
//abc.api.hydrogen.local/sanctum/csrf
按照指示,我在随后尝试登录之前进行初始调用:
this.http.get('sanctum/csrf-cookie')
.pipe(
switchMap(result => this.http.post('auth/login', {'email': email, 'password': password}))
);
Run Code Online (Sandbox Code Playgroud)
注意:我有一个拦截器,它在请求 url 前面加上 api url '//abc.api.hydrogen.local/',例如 'sanctum/csrf-cookie' 将变为 '//abc.api.hydrogen.local/sanctum/ csrf-cookie'
来自 sainttum/csrf-cookie 的响应与预期的标头一起返回:
Access-Control-Allow-Credentials: true
Set-Cookie: XSRF-TOKEN=eyJpdiI6Ilc3UkRLR1BSZ29TWVh3ZWZEQ3Y4aGc9PSIsInZhbHVlIjoiRUZBZXNFWTlZbWo5QWhIeWsrRmpjNUZVWkExSGtaT1hzUTVnSXpoaGQ4c3dFc2VLNjZsUHlUVWFmbG1uVVdKZSIsIm1hYyI6ImU1ZTAxNGFmMjAwNWRiMDhiODFjMGZhYTljYmU1NmRjYTUzYTNmNDJjNWM3YmQyM2FkY2I2OGYwNjYzNGU2MjkifQ%3D%3D; expires=Thu, 30-Apr-2020 13:35:06 GMT; Max-Age=7200; path=/; domain=localhost
Access-Control-Allow-Origin: http://localhost:8100
Run Code Online (Sandbox Code Playgroud)
但是,当我查看浏览器控制台时,我没有看到存储 > cookie 中设置任何内容。此外,后续调用“login/”时没有附加 cookie,并且我收到 CSRF 令牌不匹配错误。
我阅读了许多详细介绍类似问题的帖子,并实施了他们的建议和配置,包括以下内容:
出现此问题的原因是浏览器/角度只会将 cookie 附加到与请求来源具有相同域的请求。
为了在开发环境中解决这个问题,其中角度应用程序在本地主机上提供服务,而 Laravel 应用程序位于像 abc.api.Hydrogen.local 这样的域上,我代理了来自角度应用程序的请求:
首先确保您的请求是相对路由,例如我将调用更改为 /api/sanctum/crsf ,然后它被代理到http://abc.api.Hydrogen.local/sanctum/crsf
proxy.conf.json
然后在项目的根目录中创建代理配置:
{
"/api/*": {
"target": "http://abc.api.hydrogen.local",
"secure": false,
"changeOrigin": true,
"logLevel": "debug",
"pathRewrite": {
"^/api": ""
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后编辑angular.json
以在服务时使用代理:
"architect": {
...
"serve": {
...
"options": {
....
"proxyConfig": "proxy.conf.json"
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在您的.env
文件中添加以下内容,以确保 sainttum 将请求识别为来自第一方 SPA,并且浏览器能够读取 cookie 并将其附加到该请求。
SANCTUM_STATEFUL_DOMAINS=localhost,.hydrogen.local
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
Run Code Online (Sandbox Code Playgroud)
现在一切都应该正常了。