CSRF 令牌不匹配 Laravel 密室和 Angular http
CSRF token mismatch Laravel sanctum and Angular http
我一直在尝试实现 Laravel sanctum,但是我遇到了这个错误 "CSRF token mismatch" 即使我遵循了 Laravel Sanctum 文档中所说的一切
cors.php
配置文件
'paths' => [
'api/*',
'login',
'logout',
'sanctum/csrf-cookie'
],
'supports_credentials' => true,
kernal 是根据文档添加的,所以不要浪费 space 在这里添加它的代码
.env
文件
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost
我在这里使用 Angular 9 作为我的前端
这是我的拦截器
request = request.clone({
withCredentials: true
})
这就是我向 Laravel
发送请求的方式
this.http.get<any>(url('sanctum/csrf-cookie')).subscribe(() => {
this.http.post<any>(url('login'), { this.username, this.password })
.subscribe(success => console.log(success), error => console.log(error))
})
点击第一条路线后,我可以确认 cookie 的创建,但问题出在第二条路线 ('/login')
您需要在 header 中发送 x-csrf-token,(Angular 仅在相对 URL 而非绝对 URL 中自动包含它)
您可以创建一个解释器来执行此操作,像这样应该可以工作:
import {Injectable} from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpXsrfTokenExtractor
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
headerName = 'X-XSRF-TOKEN';
constructor(private tokenService: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.method === 'GET' || req.method === 'HEAD') {
return next.handle(req);
}
const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(this.headerName)) {
req = req.clone({headers: req.headers.set(this.headerName, token)});
}
return next.handle(req);
}
}
我的问题是我正在访问端口 8001 上的 api。当我将它 (127.0.0.1:8001) 添加到 config/sanctum 中的 'stateful' 时它起作用了。php.
我可以通过在 config/sanctum.php
中的 localhost
之前添加 http://
来解决这个问题
由此
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,127.0.0.1'
)),
对此
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'http://localhost,127.0.0.1'
)),
就我而言,这个问题是以一种奇怪的方式解决的。我去了
Illuminate\Foundation\Http\Middleware\VerifyCsrfToken 文件,在“if case”中的“handle”方法的第 76 行,有这样一行:
$this->tokensMatch($request);
出于测试目的,我return编辑了这个字符串
return response()->json($this->tokensMatch($request));
而且令人惊讶的是它将 return 一个普通的令牌。然后我 return 将所有内容都归位了,这很奇怪,但是这个错误不再存在了。
我遇到了类似的问题,但只有部分用户遇到了这个问题。我通过在 config 文件夹下的 session.php 文件中将 SESSION_DOMAIN 更改为 .localhost
来解决我的问题。
我一直在尝试实现 Laravel sanctum,但是我遇到了这个错误 "CSRF token mismatch" 即使我遵循了 Laravel Sanctum 文档中所说的一切
cors.php
配置文件
'paths' => [
'api/*',
'login',
'logout',
'sanctum/csrf-cookie'
],
'supports_credentials' => true,
kernal 是根据文档添加的,所以不要浪费 space 在这里添加它的代码
.env
文件
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost
我在这里使用 Angular 9 作为我的前端
这是我的拦截器
request = request.clone({
withCredentials: true
})
这就是我向 Laravel
发送请求的方式this.http.get<any>(url('sanctum/csrf-cookie')).subscribe(() => {
this.http.post<any>(url('login'), { this.username, this.password })
.subscribe(success => console.log(success), error => console.log(error))
})
点击第一条路线后,我可以确认 cookie 的创建,但问题出在第二条路线 ('/login')
您需要在 header 中发送 x-csrf-token,(Angular 仅在相对 URL 而非绝对 URL 中自动包含它)
您可以创建一个解释器来执行此操作,像这样应该可以工作:
import {Injectable} from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpXsrfTokenExtractor
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
headerName = 'X-XSRF-TOKEN';
constructor(private tokenService: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.method === 'GET' || req.method === 'HEAD') {
return next.handle(req);
}
const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(this.headerName)) {
req = req.clone({headers: req.headers.set(this.headerName, token)});
}
return next.handle(req);
}
}
我的问题是我正在访问端口 8001 上的 api。当我将它 (127.0.0.1:8001) 添加到 config/sanctum 中的 'stateful' 时它起作用了。php.
我可以通过在 config/sanctum.php
localhost
之前添加 http://
来解决这个问题
由此
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,127.0.0.1'
)),
对此
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'http://localhost,127.0.0.1'
)),
就我而言,这个问题是以一种奇怪的方式解决的。我去了 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken 文件,在“if case”中的“handle”方法的第 76 行,有这样一行:
$this->tokensMatch($request);
出于测试目的,我return编辑了这个字符串
return response()->json($this->tokensMatch($request));
而且令人惊讶的是它将 return 一个普通的令牌。然后我 return 将所有内容都归位了,这很奇怪,但是这个错误不再存在了。
我遇到了类似的问题,但只有部分用户遇到了这个问题。我通过在 config 文件夹下的 session.php 文件中将 SESSION_DOMAIN 更改为 .localhost
来解决我的问题。