Angular 8与Spring Boot 2.2.1 CSRF配置故障:迁移后403错误解决
嘿,针对你从Angular 5升级到8后遇到的CSRF 403问题,我来分享几个排查和解决的关键点,应该能帮你搞定!
首先得明确:Angular 8的HttpClient默认会自动处理CSRF防护,但它和Spring Security的配置需要严格匹配,不匹配就会出现令牌缺失导致的403错误。
1. 修正Spring Security的CSRF Cookie名称
你的Spring配置里已经开启了withHttpOnlyFalse()和设置了Cookie路径,但默认CookieCsrfTokenRepository生成的Cookie名称是CSRF-TOKEN,而Angular 8默认只会读取名为XSRF-TOKEN的Cookie——这大概率是核心问题!
修改你的Spring配置,显式指定Cookie名称为Angular期望的XSRF-TOKEN:
final CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse(); tokenRepository.setCookieName("XSRF-TOKEN"); // 新增这一行,和Angular匹配 tokenRepository.setCookiePath("/"); http.csrf().csrfTokenRepository(tokenRepository);
2. 确认Angular端的CSRF配置(如果需要自定义)
Angular的HttpClientModule默认已经启用了XSRF防护,但如果你的项目有自定义配置或拦截器,需要确保没有覆盖默认行为。如果需要显式配置,可以在AppModule里添加:
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule, HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', // 和Spring设置的Cookie名称一致 headerName: 'X-XSRF-TOKEN' // Angular默认就是这个,可省略 }) ] }) export class AppModule { }
3. 处理跨域场景(如果你的Angular和Spring不在同域)
如果Angular前端和Spring后端是跨域部署,还需要额外两步:
3.1 Spring端配置CORS允许携带凭证
添加CORS配置,确保允许携带Cookie和相关请求头:
http.cors(cors -> cors.configurationSource(request -> { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList("http://你的Angular域名:端口")); config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); config.setAllowedHeaders(Arrays.asList("*")); config.setAllowCredentials(true); // 关键:允许携带Cookie return config; }));
3.2 Angular端设置请求携带凭证
要么在单个请求里添加withCredentials: true:
this.http.post('/api/你的接口', 请求数据, { withCredentials: true }).subscribe(...);
要么用拦截器全局设置(更方便):
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable() export class CredentialsInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { // 克隆请求并添加携带凭证的配置 const clonedReq = req.clone({ withCredentials: true }); return next.handle(clonedReq); } }
然后在AppModule里注册这个拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: CredentialsInterceptor, multi: true } ] }) export class AppModule { }
4. 用Chrome开发者工具调试验证
最后,用Chrome的开发者工具确认关键信息:
- 打开
Application标签 →Cookies,检查是否存在名为XSRF-TOKEN的Cookie,且路径为/ - 打开
Network标签,发送POST请求后,查看请求头里是否有X-XSRF-TOKEN字段,且值和Cookie里的XSRF-TOKEN一致
如果Cookie存在但请求头没有X-XSRF-TOKEN,说明Angular没有正确读取Cookie;如果请求头有但还是403,检查Spring的CSRF令牌验证逻辑是否正常。
内容的提问来源于stack exchange,提问作者Jérémie

