sanctum 的 get 请求拿不到 authorization 头是因为浏览器普通 get(地址栏、a 标签等)不自动携带该头,需用 fetch/axios 显式设置 bearer token;若用 cookie 鉴权,则须配置 stateful 域名、credentials: 'include' 及 samesite 策略。

Sanctum 为什么 GET 请求拿不到 Authorization 头?
因为浏览器发起的普通 GET 请求(比如直接在地址栏输入、<a></a> 跳转、表单默认提交)不会携带 Authorization 请求头,这是 HTTP 规范和浏览器安全策略决定的。Sanctum 依赖该头里的 Bearer Token 验证身份,所以这类请求天然无法通过中间件鉴权。
常见错误现象:401 Unauthorized,但 Postman 或 curl 测试正常 —— 这说明后端逻辑没问题,问题出在前端调用方式上。
- 必须用 JavaScript(如
fetch或axios)显式设置Authorization: Bearer <token></token> - 不能依赖 Cookie 自动携带(除非启用了
stateful模式且域名/路径匹配) - 确保前端请求的
Origin在CORS配置中被允许(config/cors.php中的allowed_origins)
Laravel 后端如何正确配置 Sanctum 支持 GET 鉴权
重点不是“让 GET 特殊处理”,而是确保整个鉴权链路对所有 HTTP 方法一视同仁。Sanctum 默认就支持 GET,你只需要确认以下几点:
-
app/Http/Kernel.php中,api路由组已应用EnsureFrontendRequestsAreStateful::class(仅限 SPA 场景)或直接使用auth:sanctum中间件 -
config/sanctum.php的stateful域名列表包含你的前端地址(如['localhost:3000', '127.0.0.1:3000']),否则 Cookie 不会被发送 - 如果你走的是 Token 方式(非 Cookie),则完全不需要
stateful配置,只要请求带Authorization头即可
示例路由定义:
Route::middleware('auth:sanctum')->get('/api/user', function (Request $request) {
return $request->user();
});
前端 fetch 发起带鉴权的 GET 请求怎么写
关键:手动注入 Token,不要指望浏览器自动补全。Token 通常来自登录后返回的响应体(response.data.token)或本地存储(localStorage.getItem('sanctum_token'))。
- Token 必须是字符串,不能是对象或未解析的响应
- 注意空格:
Bearer <token></token>中Bearer和token之间是英文空格,不是中文或多个空格 - 如果用 Axios,推荐统一设置
defaults.headers.common['Authorization'],避免每个请求重复写
最小可用示例:
fetch('/api/user', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('sanctum_token'),
'Accept': 'application/json',
},
});
容易被忽略的跨域与 Cookie 细节
当使用 Cookie + Session 方式(即 stateful 模式)时,GET 请求能否鉴权,实际取决于浏览器是否把 Cookie 发给后端。这受三个条件联合控制:
- 后端响应必须带
Set-Cookie且SameSite=None; Secure(HTTPS 环境下)或SameSite=Lax(开发环境) - 前端请求需设置
credentials: 'include'(fetch)或withCredentials: true(Axios) -
config/sanctum.php中的stateful数组必须精确匹配当前请求来源(协议 + 域名 + 端口)
漏掉任意一项,auth:sanctum 中间件就会认为用户未登录,返回 401 —— 此时看 Network 面板,Cookie 请求头为空,基本就能定位了。











