Spring无法接收Angular请求的CSRF Token,出现403错误求助
解决Spring Boot + Angular CSRF 403问题
咱们一步步来排查你遇到的这个403问题,结合你的配置和代码,主要有几个关键细节需要调整:
1. 匹配Spring默认的CSRF请求头名称
Spring的CookieCsrfTokenRepository默认会把CSRF Token存在名为XSRF-TOKEN的Cookie中,并且期望请求头是X-XSRF-TOKEN,而不是你代码里用的_csrf。这是最可能导致403的原因——请求头名称不匹配,后端识别不到你传的Token。
2. 用Angular内置的CSRF拦截器简化处理
Angular自带了CSRF拦截器,不用手动提取Token,配置后会自动从XSRF-TOKEN Cookie中取值,然后在请求头里添加X-XSRF-TOKEN。你只需要在app.module.ts里配置:
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule, HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', // 和Spring的Cookie名对应 headerName: 'X-XSRF-TOKEN' // 和Spring期望的请求头对应 }) ] }) export class AppModule { }
配置完成后,你的请求代码可以简化,不用手动设置头:
const formData = new FormData(); formData.append("name", "name"); const postUrl = "http://localhost:8080/api/v1/testpost"; this.http.post(postUrl, formData, { withCredentials: true }) .subscribe(response => { console.log(response); });
注意这里加上了withCredentials: true,确保跨域请求时携带Cookie(CSRF Token存在Cookie里)。
3. 完善Spring的CORS配置
你的CORS配置需要补充两个关键点:允许携带Cookie(allowCredentials(true)),以及明确允许X-XSRF-TOKEN请求头:
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:4200") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 明确允许常用方法 .allowedHeaders("X-XSRF-TOKEN", "Content-Type") // 允许CSRF头和内容类型头 .allowCredentials(true); // 必须开启,允许跨域携带Cookie } }; }
4. 验证Token是否正确传输(可选排查)
如果调整后还是有问题,可以在Spring里加个过滤器,打印生成的Token和收到的Token,确认是否一致:
@Component public class CsrfTokenLoggerFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); if (csrfToken != null) { System.out.println("后端生成的CSRF Token: " + csrfToken.getToken()); System.out.println("前端传来的CSRF Token: " + request.getHeader(csrfToken.getHeaderName())); } filterChain.doFilter(request, response); } }
按上面的步骤调整后,应该就能解决403的问题了。
内容的提问来源于stack exchange,提问作者felix
相关产品推荐
相关产品推荐

