You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js+SpringBoot+Tomcat8同域跨应用认证403 CSRF报错咨询

跨应用会话保持+CSRF 403问题落地方案

直接报错原因

你碰到的HTTP Status 403 Invalid CSRF token 'null'是遗留Struts系统的CSRF拦截器默认逻辑触发的:所有非GET的状态变更请求,必须携带服务端提前生成的CSRF令牌,要么放在_csrf请求参数里,要么放在X-CSRF-TOKEN请求头里。你当前发的AJAX请求没带这两个字段,直接被拦截拒绝,这个报错和登录态没打通是两个独立问题,别混在一起排查。

长期最优方案(适配你现有架构,改造成本最低)

你当前的架构天然适合做无感知跨应用登录,三个应用同根域名、同服务器、同F5入口、同数据库、同SSL证书,完全不需要搭重量级SSO系统,做共享会话+统一CSRF透传就行:

  • 第一步:打通三个应用的会话存储
    废弃各应用独立生成会话的逻辑,统一将会话存在共享Redis中,三个应用的Cookie配置完全对齐:

Cookie域设置为.mydomain.com,Cookie路径设置为/,Cookie名称统一用JSESSIONID,开启HttpOnly、Secure属性,SameSite设为Lax
技术选型直接用Spring Session即可,SpringBoot侧原生支持,遗留Tomcat+Struts应用只需要加Spring Session的适配过滤器,不需要改业务代码。注意序列化规则要统一,避免Tomcat原生序列化和SpringBoot序列化不兼容导致会话读失败。
这一步做完之后,用户在任意一个应用完成登录,登录态会写入共享会话,另外两个应用收到请求后直接从共享会话读用户信息,完全不需要额外发AJAX做"同步登录",用户全程无感知,也不会出现重复登录的问题。

  • 第二步:统一CSRF令牌逻辑,解决403问题
    不要让三个应用各自生成、校验独立的CSRF令牌,统一做全局令牌透传:
    1. 用户首次访问任意应用时,生成全局唯一CSRF令牌存入共享会话,同时将令牌写入根域下的独立Cookie(关闭HttpOnly属性,保证前端JS可读取)
    2. React前端全局配置请求拦截器,所有发往mysiteapp.mydomain.com和mysite.mydomain.com/old的非GET请求,自动从Cookie中读取CSRF令牌,放到X-CSRF-TOKEN请求头中携带
    3. 两个后端的CSRF拦截器统一修改校验逻辑:不再生成本地令牌,直接从共享会话中读取预存的全局令牌,和请求携带的令牌做比对即可
      如果不想改遗留Struts系统的老代码,可以直接在F5上做转发规则:所有匹配/old路径的非GET请求,先从请求携带的会话中取出预存的CSRF令牌,自动补全X-CSRF-TOKEN请求头或_csrf请求参数后再转发给后端Tomcat,零代码改造成本。

临时调试方案(快速验证逻辑用)

如果要先快速跑通你当前的AJAX同步登录逻辑,不用等全量改造:

  1. 先手动访问一次遗留系统的任意页面,从页面源码的meta标签、隐藏表单域中拿到Struts生成的_csrf令牌,或者从遗留系统返回的响应头、Cookie中提取令牌
  2. 发AJAX请求时开启withCredentials: true保证Cookie正常携带,同时把拿到的CSRF令牌放到X-CSRF-TOKEN请求头里,就能绕过当前的403拦截
    注意这个方案只是临时调试用,长期运行会因为三个应用会话过期时间不一致、Cookie作用域不匹配出现随机掉登录的问题,不建议生产用。

常见踩坑提醒

  • 不要给不同应用设置独立的Cookie路径,比如给遗留应用单独设Cookie路径为/old,会导致React侧写入的Cookie无法被/old路径的请求携带
  • CSRF令牌不要存在LocalStorage里,存在根域Cookie下配合SameSite属性即可满足安全要求
  • F5如果开了会话保持,要确保会话保持规则和应用侧的Cookie规则对齐,避免请求被转发到错误节点读不到会话

内容的提问来源于stack exchange,提问作者Bob J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:36:29