React客户端跨域场景下如何安全存储JWT token?
跨域部署场景下JWT存储安全方案及建议
核心适用场景说明
针对你当前React前端部署在abc.com、Odoo后端部署在xyz.com的完全跨域场景,以下是两种经过生产验证的安全存储方案,按优先级从高到低排列:
方案1:HttpOnly安全Cookie(优先推荐)
很多人误认为跨域场景无法使用Cookie,实际只要做对应配置即可实现,这一安全性最高的存储方案:
- 后端Odoo侧配置Cookie属性:
- 开启
HttpOnly:禁止前端JS读取Cookie内容,从根源避免XSS攻击窃取JWT - 同时设置
SameSite=None+Secure:跨域场景必须将SameSite设为None,且要求所有请求必须走HTTPS协议 - 明确
Domain属性设置为xyz.com:指定Cookie归属于后端域名 - 按需设置
Max-Age控制有效期,避免Cookie长期有效
- 开启
- 前端React侧配置:
- 所有发往后端
xyz.com的请求开启携带凭证配置,使用axios的话配置axios.defaults.withCredentials = true,使用fetch的话配置credentials: 'include' - 该方案下JWT完全不需要前端代码处理存储、读取、拼接请求头,浏览器会自动在跨域请求时携带对应Cookie,大幅降低前端侧的安全风险
- 所有发往后端
- 后端Odoo侧CORS配置要求:
Access-Control-Allow-Origin必须明确指定https://abc.com,不能设置为通配符*- 开启
Access-Control-Allow-Credentials: true配置
该方案是当前跨域场景下安全性最高的选择,完全规避了前端JS操作token带来的XSS泄露风险
方案2:浏览器内存存储(次选,适合会话有效期短的JWT)
如果你的业务场景无法满足Cookie的配置要求,可以选择将JWT存储在React的全局状态中(比如useContext、Redux等状态管理工具):
- 优势:页面刷新后token会自动丢失,XSS攻击能窃取到的token有效期极短,风险远低于本地持久化存储
- 适配要求:
- 每次发起后端请求时,手动将JWT拼接在
Authorization请求头中,格式为Bearer ${token} - 如果需要支持刷新页面不丢失登录态,可以搭配后端返回的有效期极短的refresh token,refresh token同样存储在HttpOnly Cookie中,JWT过期时前端调用刷新接口静默更新即可
- 每次发起后端请求时,手动将JWT拼接在
- 绝对禁止的操作:
- 不要把JWT存储在
localStorage/sessionStorage中:这两个存储区域可以被前端JS直接读取,一旦出现XSS漏洞token会被直接窃取,且长期有效 - 不要把JWT存储在普通前端可读取的Cookie中:和localStorage的风险完全一致,没有任何安全性提升
- 不要把JWT存储在
通用安全加固建议
无论选择哪种存储方案,都需要做如下安全加固:
- 所有前后端通信必须走HTTPS,禁止HTTP明文传输敏感信息
- JWT的payload不要存储敏感信息,JWT本身仅为base64编码而非加密,所有人都可以解码查看内容
- 后端配置JWT短期有效期,建议不超过2小时,搭配refresh token实现无感刷新
- 前端做好XSS防护:React默认已经做了大部分内容转义,注意避免直接使用
dangerouslySetInnerHTML、eval等危险API,引入第三方依赖前做好安全审计 - 后端做好CSRF防护:如果使用Cookie方案,直接开启Odoo自带的CSRF防护机制即可
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

