如何使用 Spring Boot 和 Angular 7 配置 CRSF

How to configure CRSF with Spring Boot and Angular 7

我正在使用 Spring 引导和来自 Spring.io sight 的 Angular 文章。登录页面部分,部分添加注销。我在配置 CRSF 时遇到问题。他们写这个

The last choice is the best because Angular has built in support for CSRF (which it calls "XSRF") based on cookies.

但是在Angular7中好像不是这样(文章中他们用的是angular4)。因为当我在 CsrfFilter 中放置一个断点时,方法 doFilterInternal returns 我一个空的 CRSF 令牌和浏览器响应是

{"timestamp":"2019-04-30T08:15:16.593+0000","status":403,"error":"Forbidden","message":"Forbidden","path":"/api/logout"}

我尝试添加

HttpXsrfTokenExtractor

对于应用程序的 Angular 部分,然后在发送请求时像这样设置 X-XSRF-TOKEN

const token = this.tokenExtractor.getToken();
    this.httpClient.post('api/logout', {}, {headers: new HttpHeaders().set('X-XSRF-TOKEN', token)}).pipe(finalize(() => {
      this.userService.user.authenticated = false;
      this.userService.user.name = '';
      this.router.navigateByUrl('login');
    })).subscribe();

但是我得到这个错误

ERROR TypeError: Cannot read property 'length' of null
    at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.applyUpdate (http.js:241)
    at http.js:212
    at Array.forEach (<anonymous>)
    at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.init (http.js:212)
    at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.forEach (http.js:277)
    at Observable._subscribe (http.js:1529)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:43)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:29)
    at subscribeTo.js:21
    at subscribeToResult (subscribeToResult.js:11)

我并没有低估它。

我希望我可以注销并且 CsrfFilter.class 会显示实际的 CSRF 令牌。

我终于知道是怎么回事了。 出于开发目的,我在 Angualar 应用程序 proxy.conf.json 中设置我的所有请求都应代理到 Spring Boot 应用程序,因为由于 Angualr 应用程序中的动态重新加载内容,我分别开发了这两个应用程序,但最后我想要一个应用程序。使用 maven-fronten-plugin,我构建 Angual 应用程序并将 dist 文件夹复制到 Spring Boot 中的静态内容。 proxy.conf.json 是

{
  "/api/*": {
    "target": "http://localhost:8080",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true
  }
}

我不知道我可以只用“/**”来代理我所有的电话。所以在 Spring 启动应用程序中,我在应用程序属性中设置

server.servlet.context-path=/api

看来这个配置有些怎么破坏正常的流量。因此,我从 Spring 启动应用程序中删除了上下文路径,并更改了 Angular 应用程序的代理配置。现在一切正常。