如何在Laravel+JS环境下安全持久化浏览器中的access_token?
解决Sanctum API页面重载后access_token丢失的安全方案
针对你遇到的问题,这里有几个实用且安全的解决方案,都是基于Sanctum特性和前端安全最佳实践:
方案一:改用Sanctum的Cookie认证模式(推荐)
这是Sanctum官方为SPA场景设计的标准方案,完全不用手动处理token存储:
- 后端配置:在
config/sanctum.php的stateful数组中添加你的前端域名;确保CORS配置允许凭证(Laravel的cors.php里supports_credentials设为true);登录接口无需返回access_token,直接用Auth::attempt()完成认证,后端会自动设置带有HttpOnly、Secure、SameSite=Strict属性的会话Cookie。 - 前端配置:发起请求时开启
withCredentials(比如Axios中设置axios.defaults.withCredentials = true),浏览器会自动在每次请求中带上Cookie,页面重载后会话依然有效,后端通过Auth::user()就能获取当前登录用户。 - 优势:完全避免前端操作token,从根源上杜绝XSS窃取token的风险,同时Sanctum自带CSRF防护,无需担心CSRF攻击。
方案二:安全存储access_token到localStorage+强化XSS防护
如果一定要用Bearer token模式,通过以下措施可大幅降低localStorage存储的风险:
- 严格XSS防护:所有用户输入内容都做HTML转义,避免注入恶意脚本;启用Content-Security-Policy(CSP),限制仅允许信任域名加载脚本,禁止内联脚本和
eval执行。 - 缩短token有效期:将
access_token的过期时间设为15-30分钟,同时实现刷新token机制,过期后用存于HttpOnly Cookie的长时效refresh_token换取新的access_token。 - 页面重载恢复:每次页面加载时,从localStorage读取
access_token,设置到请求头的Authorization: Bearer {token}中即可。
方案三:HttpOnly Cookie存refresh_token,localStorage存access_token
这是兼顾安全性和灵活性的折中方案:
- 登录时后端返回短时效的
access_token,前端存入localStorage用于日常请求;同时后端设置带有HttpOnly属性的refresh_tokenCookie。 - 当
access_token过期时,前端发起刷新请求(浏览器自动带上refresh_token Cookie),后端验证后返回新的access_token,前端更新localStorage中的值。 - 注意:refresh_token需设置合理过期时间,且刷新接口要验证请求的用户代理、IP等信息,配合Sanctum的CSRF防护进一步降低风险。
内容的提问来源于stack exchange,提问作者michael-mammut
相关产品推荐
相关产品推荐

