要从Spring Security获取CSRF令牌,可以使用Angular的HttpClient来发送GET请求获取CSRF令牌。
首先,确保你的Spring Security配置中启用了CSRF保护,例如:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
在Angular应用中,你可以创建一个服务来获取CSRF令牌。例如,创建一个名为CsrfTokenService
的服务:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable()
export class CsrfTokenService {
constructor(private http: HttpClient) { }
getCsrfToken() {
return this.http.get('/api/csrf-token', { responseType: 'text' });
}
}
在上面的代码中,我们使用HttpClient发送一个GET请求来获取CSRF令牌。注意,我们将responseType
设置为text
,以便获取CSRF令牌的字符串形式。
然后,在需要使用CSRF令牌的地方,可以注入CsrfTokenService
并调用getCsrfToken
方法来获取CSRF令牌。例如,你可以在一个名为CsrfTokenInterceptor
的拦截器中添加CSRF令牌到请求头中:
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { CsrfTokenService } from './csrf-token.service';
@Injectable()
export class CsrfTokenInterceptor implements HttpInterceptor {
constructor(private csrfTokenService: CsrfTokenService) { }
intercept(req: HttpRequest, next: HttpHandler): Observable> {
return this.csrfTokenService.getCsrfToken().pipe(
switchMap(csrfToken => {
const headers = req.headers.set('X-CSRF-TOKEN', csrfToken);
const csrfReq = req.clone({ headers });
return next.handle(csrfReq);
})
);
}
}
在上面的代码中,我们通过调用csrfTokenService.getCsrfToken()
方法获取CSRF令牌,并将其添加到请求头的X-CSRF-TOKEN
字段中。然后,我们使用clone
方法创建一个新的请求,并将CSRF令牌添加到新请求的请求头中,最后通过next.handle
方法继续处理请求。
最后,将CsrfTokenInterceptor
添加到Angular的HTTP拦截器链中。例如,在AppModule
中的providers
数组中添加:
import { CsrfTokenInterceptor } from './csrf-token.interceptor';
@NgModule({
// ...
providers: [
// ...
{
provide: HTTP_INTERCEPTORS,
useClass: CsrfTokenInterceptor,
multi: true
}
],
// ...
})
export class AppModule { }
这样,当Angular应用发送请求时,就会自动获取并添加CSRF令牌到请求头中。