You need to enable JavaScript to run this app. Angular请求Laravel CSRF接口时每次生成新令牌,与浏览器请求行为不一致的原因
优惠活动
大模型
产品
解决方案
定价
更多

Angular请求Laravel CSRF接口时每次生成新令牌,与浏览器请求行为不一致的原因

根本原因分析

Laravel CSRF 令牌的绑定规则

Laravel 的 csrf_token() 返回值完全绑定当前会话(Session):

  • 令牌会存储在服务端 Session 上下文中
  • 会话身份完全靠客户端携带的 SESSION Cookie(Laravel 默认会话 Cookie 名)识别
  • 只有客户端携带的 Cookie 和服务端 Session 匹配时,才会返回同一个固定令牌;如果没有有效会话 Cookie,Laravel 会生成全新 Session,返回全新的 CSRF 令牌。

不同场景的行为差异来源

直接浏览器访问、Postman 请求返回固定令牌的原因

  • 直接访问 http://token.loc/token 属于同域请求,浏览器会自动携带该域名下的所有 Cookie,Laravel 能识别到同一个 Session,因此令牌固定。
  • Postman/Insomnia 这类 API 工具会自动保存接口返回的所有 Cookie,后续请求自动携带,也能维持同一个 Session,因此令牌固定。

Angular 跨域请求每次返回新令牌的原因

你的前端运行在 http://localhost:4200,请求的接口在 http://token.loc,属于跨域请求,存在两个默认限制:

  1. Angular HttpClient 默认不对跨域请求携带 Cookie:你当前的请求没有开启 withCredentials 配置,浏览器会自动丢弃跨域请求中需要传递的 SESSION Cookie,Laravel 每次都将请求识别为新访客,生成全新 Session 和令牌。
  2. 就算开启了前端的凭证携带配置,如果 Laravel 端 CORS 规则没有允许跨域凭证,浏览器也会拦截 Cookie 的传递。

修复方案

1. 调整 Angular 端请求配置

修改 token.service.ts 的 get 方法,开启跨域请求携带 Cookie:

get(): Observable<any>  {
  return this.http.get(this.url, {
    withCredentials: true // 跨域请求自动携带 Cookie(含 Session Cookie)
  });
}

如果所有接口都需要携带凭证,也可以封装全局 HTTP 拦截器统一配置该参数,不用每个请求单独设置。

2. 调整 Laravel 端 CORS 配置

修改 Laravel 项目的 config/cors.php(如果没有该文件,可执行 php artisan vendor:publish --tag=cors 生成):

  • 将 supports_credentials 设为 true,允许跨域请求携带凭证
  • allowed_origins 不能使用通配符 *,需要明确指定前端地址 http://localhost:4200
    参考配置示例:
'paths' => ['token', 'api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:4200'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'supports_credentials' => true,
'max_age' => 0,

3. 适配跨站 Cookie的 SameSite 限制

现代浏览器默认对跨站 Cookie 启用 SameSite=Lax 限制,如果 localhost 和 token.loc 被浏览器判定为跨站,还需要调整 Laravel 的 Session 配置(修改 config/session.php):

  • 将 same_site 设为 'none'
  • 本地 HTTP 开发环境将 secure 设为 false(生产环境必须设为 true 配合 HTTPS 部署)
'same_site' => 'none',
'secure' => env('SESSION_SECURE_COOKIE', false),

提示:Chrome 浏览器要求 SameSite=None 的 Cookie 必须同时配置 Secure 属性,本地 HTTP 环境如果适配麻烦,可以直接用 Nginx 反向代理,把前端的 localhost:4200/api/* 路径转发到 token.loc 服务,完全规避跨域问题。


内容的提问来源于stack exchange,提问作者Daniel Częstki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.09 03:45:04