Laravel Sanctum+Nuxt3 API认证401问题及相关疑问
我正在搭建一个纯API令牌认证的应用,后端用Laravel,前端用Nuxt3。目前Laravel配置基本没问题,Nuxt登录后能成功拿到用户数据和令牌,但访问带auth:sanctum的受保护端点时返回401未授权,手动在请求头加Bearer令牌就能正常请求。之前以为设置withCredentials: true会自动在请求头带Authorization Bearer令牌,但实际没生效。另外还有两个疑问:
- 自定义
auth_tokencookie是否有必要? - 将令牌存在localStorage里有没有风险?
后端Laravel登录返回令牌代码
$token = Auth::user()->createToken('basic-app-token')->plainTextToken; $cookie = cookie('auth_token', $token, 30, null, null, false, true, false, 'Strict'); return $this->successfullRequest($response, $message,200)->withCookie($cookie);
前端Nuxt登录请求代码
await axios.get('http://localhost:5000/sanctum/csrf-cookie', { withCredentials: true }); const {data: {data: {user, token}}} = await axios.post('http://localhost:5000/api/v1/auth/login', userData, { headers: { 'Content-Type': 'application/json' }, withCredentials: true, });
前端访问受保护端点代码
const request = await axios.get('http://localhost:5000/api/v1/company', { headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, withCredentials: true }); console.log(request); // 返回401
401问题排查与解决
纠正
withCredentials: true的认知误区withCredentials: true的作用只是让浏览器自动携带请求相关的cookie,不会自动把cookie里的auth_token提取出来放到Authorization请求头里。Laravel Sanctum的令牌认证要求请求头必须包含Authorization: Bearer {token},所以你得手动处理令牌的读取和请求头注入。统一处理请求头(推荐用axios拦截器)
登录成功后,要么把返回的token存在Nuxt状态管理(比如Pinia)里,要么从cookie中读取,然后通过axios拦截器自动给所有请求加上Authorization头:
// 在Nuxt的plugins/axios.js中配置拦截器 export default defineNuxtPlugin((nuxtApp) => { const axios = nuxtApp.$axios; axios.interceptors.request.use(config => { // 从cookie读取令牌(或从状态管理中取) const token = useCookie('auth_token').value; if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); });
- Laravel端关键配置检查
- 确认
config/sanctum.php的stateful数组包含你的Nuxt域名(比如localhost:3000) - 确认
config/cors.php中supports_credentials设为true,allowed_origins包含Nuxt的访问地址
自定义auth_token cookie是否必要?
没必要。Laravel Sanctum在API令牌认证场景下,不需要额外自定义cookie。直接把令牌返回给前端,由前端选择存储方式更灵活。如果非要存cookie,需注意要把HttpOnly设为false(否则前端无法读取令牌注入请求头),但这会带来XSS攻击风险,反而不如让前端自行管理令牌。
localStorage存令牌的风险?
有明确风险:
- XSS攻击威胁:如果前端页面被注入恶意脚本,脚本可以直接读取localStorage中的令牌,发送到攻击者服务器,进而冒充用户执行操作。
- 跨标签页共享泄露:localStorage是同源跨标签页共享的,只要其中一个标签页被攻陷,所有同源标签页的令牌都会泄露。
相对更安全的替代方案:
- 用sessionStorage存储令牌:关闭标签页即失效,风险比localStorage低,但仍存在XSS风险。
- 结合Nuxt状态管理(Pinia)+ 页面刷新时从非HttpOnly cookie读取令牌,同时设置短有效期并配合刷新令牌机制,平衡安全性和用户体验。
内容的提问来源于stack exchange,提问作者henrbu

