如何访问 Angular 中的 XSRF cookie 值?
How to access XSRF cookie value in Angular?
过去 7 个小时我一直在为此工作,但似乎没有取得任何进展。我正在尝试让我的 XSRF-TOKEN 可用于前端 (Angular 6)。但是,它似乎永远无法使用。当我在网络选项卡中执行分析并在 "Cookie" 下查看时,它似乎闪闪发光。但是,如果我使用 Angular 的 CookieService 并尝试检索它,则没有任何结果。
注意事项:
- 当 运行 在我的本地计算机上时,我能够取出 XSRF-TOKEN 并将其放置在以后的 header 请求中。
- 当两个前端和后端 (Spring-boot) 托管在两个不同的主机但在同一域下时,就会出现此问题。例如:前端可以是 frontend.home.com;后端可以是 backend.home.com.
- HttpOnly 设置为 False。
- Angular 的 withCredentials 属性 也设置为 true。
如果有任何关于如何处理这个看似微不足道但令人沮丧的问题的建议,我将不胜感激。
谢谢。
后端:
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of URL").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.ignoringAntMatchers("List of API to ignore CSRF Token")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
@Autowired
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
前端:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let newHeaders: HttpHeaders = req.headers;
let csrfToken = this.cookieService.get("XSRF-TOKEN");
if (csrfToken === null || csrfToken === undefined) {
newHeaders = newHeaders.append('X-XSRF-TOKEN', 'undefined');
} else {
newHeaders = newHeaders.append('X-XSRF-TOKEN', csrfToken);
}
const authReq = req.clone({headers: newHeaders, withCredentials: true});
return next.handle(authReq);
}
此外,当我查看开发人员工具时,我看到了三个不同的域。
- home.com
- backend.home.com(XSRF cookie 只能在这里找到,其他地方无法访问)
- frontend.home.com
根据编辑和评论,您可能需要将 CSRF cookie 的 Cookie 域更改为在 home.com
域上设置,而不是仅在 backend.home.com
域上设置。您可以通过更改 CookieCsrfTokenRepository
:
来实现
CookieCsrfTokenRepository repository = CookieCsrfTokenRepository.withHttpOnlyFalse();
repository.setCookieDomain("home.com");
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of URL").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.ignoringAntMatchers("List of API to ignore CSRF Token")
.csrfTokenRepository(repository)
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
请参阅前两行,其中像我上面写的那样设置存储库,然后将其用作令牌存储库。
过去 7 个小时我一直在为此工作,但似乎没有取得任何进展。我正在尝试让我的 XSRF-TOKEN 可用于前端 (Angular 6)。但是,它似乎永远无法使用。当我在网络选项卡中执行分析并在 "Cookie" 下查看时,它似乎闪闪发光。但是,如果我使用 Angular 的 CookieService 并尝试检索它,则没有任何结果。
注意事项:
- 当 运行 在我的本地计算机上时,我能够取出 XSRF-TOKEN 并将其放置在以后的 header 请求中。
- 当两个前端和后端 (Spring-boot) 托管在两个不同的主机但在同一域下时,就会出现此问题。例如:前端可以是 frontend.home.com;后端可以是 backend.home.com.
- HttpOnly 设置为 False。
- Angular 的 withCredentials 属性 也设置为 true。
如果有任何关于如何处理这个看似微不足道但令人沮丧的问题的建议,我将不胜感激。
谢谢。
后端:
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of URL").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.ignoringAntMatchers("List of API to ignore CSRF Token")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
@Autowired
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
前端:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let newHeaders: HttpHeaders = req.headers;
let csrfToken = this.cookieService.get("XSRF-TOKEN");
if (csrfToken === null || csrfToken === undefined) {
newHeaders = newHeaders.append('X-XSRF-TOKEN', 'undefined');
} else {
newHeaders = newHeaders.append('X-XSRF-TOKEN', csrfToken);
}
const authReq = req.clone({headers: newHeaders, withCredentials: true});
return next.handle(authReq);
}
此外,当我查看开发人员工具时,我看到了三个不同的域。
- home.com
- backend.home.com(XSRF cookie 只能在这里找到,其他地方无法访问)
- frontend.home.com
根据编辑和评论,您可能需要将 CSRF cookie 的 Cookie 域更改为在 home.com
域上设置,而不是仅在 backend.home.com
域上设置。您可以通过更改 CookieCsrfTokenRepository
:
CookieCsrfTokenRepository repository = CookieCsrfTokenRepository.withHttpOnlyFalse();
repository.setCookieDomain("home.com");
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of URL").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.ignoringAntMatchers("List of API to ignore CSRF Token")
.csrfTokenRepository(repository)
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
请参阅前两行,其中像我上面写的那样设置存储库,然后将其用作令牌存储库。