【问题标题】:Why am I getting a 403 error “CSRF token missing” with Spring boot+ Angular 7?为什么我在使用 Spring Boot Angular 7 时收到 403 错误“CSRF 令牌丢失”?
【发布时间】:2019-04-30 14:06:24
【问题描述】:

我在 Spring Boot+Angular 7 应用程序中实现 csrf,我担心的是当我登录时,我可以毫无问题地登录应用程序。但是登录后csrf cookie没有改变,所以我从服务器收到403(CSRF已过期)错误,

但是当我刷新时它会正常工作。主要原因是 cookie 没有正确获取,我不知道问题出在哪里,比如来自客户端或服务器端。请帮忙

我正在分享我的代码

Spring 引导代码

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().csrf() // csrf config starts here
        .csrfTokenRepository(csrfTokenRepository())
        .ignoringAntMatchers("/", "/login", "/captcha-servlet", "/validateOTP", "supportApp/logout")
        .and()
        .addFilterAfter(new CustomCsrfFilter(), CsrfFilter.class);
}


private CsrfTokenRepository csrfTokenRepository() {
    HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
    repository.setHeaderName("X-XSRF-TOKEN");
    return repository;
}

CSRF 过滤器

public class CustomCsrfFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
        if (csrf != null) {
            Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
            String token = csrf.getToken();
            cookie = new Cookie("XSRF-TOKEN", token);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
        filterChain.doFilter(request, response);
    }
}

Angular CSRF 代码

import { HttpClient, HttpXsrfTokenExtractor, HttpHeaders } from '@angular/common/http';

constructor(private http: HttpClient, private tokenExtractor: HttpXsrfTokenExtractor) { }

const _csrf_token = this.tokenExtractor.getToken() as string;
return this.http.post(this._singleuserUrl, uid, {headers: new HttpHeaders().set('X-XSRF-TOKEN', _csrf_token), withCredentials: true});

【问题讨论】:

    标签: spring-boot angular7 csrf-token


    【解决方案1】:

    您似乎忘记将 HttpClientXsrfModule 导入 app.module.ts

    在 Angular 6 中为我工作。

    app.module.ts

        imports: [
        HttpClientXsrfModule.withOptions({
          cookieName: "XSRF-TOKEN",
          headerName: "X-XSRF-TOKEN"
          }),
        ...
      ],
      providers: [
        { provide: HTTP_INTERCEPTORS, useClass: HttpXSRFInterceptor, multi: true },
        ...
      ],
    

    另外,我使用拦截器将令牌设置为 HEADER

    HttpXSRFInterceptor

    @Injectable()
    export class HttpXSRFInterceptor implements HttpInterceptor {
    
      constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
      }
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const headerName = 'XSRF-TOKEN';
        const respHeaderName = 'X-XSRF-TOKEN';
        let token = this.tokenExtractor.getToken() as string;
        if (token !== null && !req.headers.has(headerName)) {
          req = req.clone({ headers: req.headers.set(respHeaderName, token) });
        }
        return next.handle(req);
      }
    }
    

    此外,您可以使用邮递员来澄清服务器中的配置是否正常。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 2019-06-20
      • 2020-11-20
      • 2019-11-03
      • 2017-09-10
      • 2020-08-03
      • 2018-03-15
      相关资源
      最近更新 更多