Django前后端分离双服务:Token存储与API鉴权方案咨询
前端令牌存储与API身份验证最优方案
一、前端存储Access Token和Refresh Token的最优方式
Access Token
- 优先存在内存中:比如用前端框架的全局状态管理(如Pinia、Redux)或者组件内部状态,这种方式不会被XSS攻击持久化窃取,页面刷新后令牌会丢失,安全性最高。缺点是页面刷新后需要重新获取令牌(用Refresh Token自动刷新或引导用户重新登录)。
- 禁止存储在
localStorage/sessionStorage:这两种存储方式可被JS直接读取,XSS攻击一旦成功,攻击者就能窃取令牌并长期调用API,风险极高。 - 特殊场景的妥协方案:如果必须实现页面刷新后保持登录状态,可以将Access Token存入带有HttpOnly、Secure、SameSite=Strict属性的Cookie,但要配合严格的CSRF防护,且Access Token有效期要尽可能短(比如15分钟)。
Refresh Token
- 必须存储在HttpOnly、Secure、SameSite=Strict/Lax的Cookie中:HttpOnly属性会禁止JS读取Cookie,从根源上避免XSS窃取;Secure确保Cookie仅通过HTTPS传输;SameSite限制Cookie仅在同站请求中携带,降低CSRF风险。
- 绝对禁止存入内存或
localStorage/sessionStorage:Refresh Token用于获取新的Access Token,一旦被盗,攻击者可以持续获取有效令牌,危害极大。
二、调用API时身份验证的最优方案
- 标准Bearer Token认证:将Access Token放在请求头的
Authorization字段中,格式为Bearer <your-access-token>。后端可以用Django REST Framework(DRF)的JWTAuthentication组件(配合djangorestframework-simplejwt库)解析验证令牌,这是REST API的通用标准。 - 自动处理令牌过期:前端拦截所有API请求,当收到
401 Unauthorized响应时,触发Refresh Token刷新流程:调用后端的令牌刷新接口(此时浏览器会自动携带存储在Cookie中的Refresh Token),获取新的Access Token后,自动重新发起原请求。 - 跨域场景配置:若前后端域名不同,需在后端配置CORS(通过
django-cors-headers库),允许前端域名携带Authorization请求头;同时确保Refresh Token的Cookie设置SameSite=Lax,并将前端域名加入后端的CSRF_TRUSTED_ORIGINS列表,避免CSRF拦截。 - 后端令牌逻辑优化:使用
djangorestframework-simplejwt配置短有效期的Access Token(15分钟内)和较长有效期的Refresh Token(如7天),开启滚动刷新机制——每次刷新令牌时返回新的Refresh Token,缩短被盗后的风险窗口。
内容的提问来源于stack exchange,提问作者user4627923
相关产品推荐
相关产品推荐

