React应用CSRF Token无法生效 跨端口部署场景能否正常使用?
CSRF跨源部署问题解决方案
问题1:跨服务部署场景下CSRF Token能否正常生效?
可以正常生效。CSRF防护机制本身不强制要求前后端同源,核心校验逻辑是验证请求携带的Token是否和服务端下发的一致,只要处理好跨源场景下的浏览器权限限制即可。
你当前的部署场景(前端localhost:3000、后端localhost:8000)属于跨源场景(端口不同判定为不同源),默认浏览器会限制跨源请求的凭证传递、自定义头读写,这也是你目前Token失效的核心诱因。
问题2:当前开发场景能否实现CSRF正常运行?
完全可以,只要按以下规则调整前后端配置即可:
- 服务端CORS配置要求:
- 开启
Access-Control-Allow-Credentials: true Access-Control-Allow-Origin不能使用通配符*,必须明确指定允许的源为http://localhost:3000- 若CSRF Token通过自定义响应头返回给前端,需要配置
Access-Control-Expose-Headers允许前端读取该头,比如Access-Control-Expose-Headers: X-CSRF-Token - 允许前端携带CSRF Token的自定义请求头,配置
Access-Control-Allow-Headers: X-CSRF-Token
- 开启
- 服务端Cookie配置要求(如果CSRF Token存在Cookie中):
- 开发环境下
SameSite属性设置为Lax即可(如果设置为None必须同时开启Secure属性,http协议的本地开发环境会不生效) Domain属性设置为localhost,保证前后端都能正常读取Cookie
- 开发环境下
- React前端配置要求:
- 发起请求时开启跨源凭证携带:
fetch请求添加credentials: 'include'参数,axios请求设置withCredentials: true - 发送非GET请求时,主动将获取到的CSRF Token添加到请求头中
- 发起请求时开启跨源凭证携带:
axios统一配置示例
import axios from 'axios' const request = axios.create({ baseURL: 'http://localhost:8000', withCredentials: true }) // 请求拦截器统一注入CSRF Token request.interceptors.request.use(config => { // 从Cookie中读取服务端下发的CSRF Token,key根据你的实际配置调整 const csrfToken = document.cookie .split('; ') .find(item => item.startsWith('csrfToken=')) ?.split('=')[1] if (csrfToken) { config.headers['X-CSRF-Token'] = csrfToken } return config }) export default request
内容的提问来源于stack exchange,提问作者Darius
相关产品推荐
相关产品推荐

