CSRF Token 刷新后前端怎么同步更新?
我在用 Axios 拦截器处理 CSRF Token 过期的情况,后端返回 419 时会刷新 token 并在响应头里带新的 XSRF-TOKEN。但我不确定怎么安全地把新 token 应用到后续请求里,现在每次刷新页面才生效,体验很差。
我试过在拦截器里直接更新 axios.defaults.headers.common[‘X-XSRF-TOKEN’],但好像没起作用,或者有竞态问题?
axios.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 419) {
const newToken = error.response.headers['xsrf-token'];
if (newToken) {
axios.defaults.headers.common['X-XSRF-TOKEN'] = newToken;
// 这里要不要重新发起原请求?怎么保证其他并发请求也用新 token?
}
}
return Promise.reject(error);
}
);
首先你需要在拦截器里做两件事:
1. 更新axios的默认headers
2. 更新cookie里的
XSRF-TOKEN(因为axios默认是从cookie读取的)关键是要用
document.cookie同步更新cookie,不然下次请求axios还是会用旧的。然后重新发起原请求也很重要,不然用户得手动刷新页面。改进后的代码大概这样:
关于竞态问题,这样处理就够了。因为axios内部会用最新的headers,其他并发请求会自动带上新token。我实测过没问题的,除非你项目里有特别奇葩的封装。
ps. 记得让后端设置
Access-Control-Expose-Headers把xsrf-token暴露出来,不然前端拿不到响应头。