Angular HTTP 拦截器自定义预检

Posted

技术标签:

【中文标题】Angular HTTP 拦截器自定义预检【英文标题】:Angular HTTP interceptor custom preflight 【发布时间】:2021-06-15 11:39:54 【问题描述】:

我正在编写一个与后端 API 通信的应用程序,该 API 需要在每个请求上设置 XSRF-TOKEN 标头。我通过以下 HTTP 拦截器实现了这一点:

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> 
  const modifiedReq = request.clone(
    headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
  );

  return next.handle(modifiedReq);

现在我需要处理尚未设置XSRF-TOKEN cookie 的情况。在这种情况下,我需要预先检查我发送的请求,该请求会在后端 API 上命中特定的 /csrf 端点,这将返回一个 Set-Cookie 标头以设置 XSRF-TOKEN

作为一个快速而肮脏的测试(没有重构以删除重复代码)我尝试了这个:

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> 
  if (!this.cookieService.check('XSRF-TOKEN')) 
    this.apiService.csrf().subscribe(() => 
      const modifiedReq = request.clone(
        headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
      );

      return next.handle(modifiedReq);
    );
  

  const modifiedReq = request.clone(
    headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
  );

  return next.handle(modifiedReq);

但这显然会导致对/csrf端点的请求无限循环,因为拦截器内的每个HTTP请求都会被自己拦截......

我怎样才能实现我的目标?

【问题讨论】:

我也在这里回答了这个问题 (***.com/a/66704512/7255496) - 看看。 【参考方案1】:

让对/csrf的请求完成而不拦截它:

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> 

  if (request.url === '/csrf') 
    return next.handle(request);
  

  if (!this.cookieService.check('XSRF-TOKEN')) 
    this.apiService.csrf().subscribe(() => 
      const modifiedReq = request.clone(
        headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
      );

      return next.handle(modifiedReq);
    );
  

  const modifiedReq = request.clone(
    headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
  );

  return next.handle(modifiedReq);

【讨论】:

以上是关于Angular HTTP 拦截器自定义预检的主要内容,如果未能解决你的问题,请参考以下文章

Angular:如何扩展 HttpClient?

http跨域预检问题

angular中如何设置全局的ajax请求?

MVC6 Cors - 拦截预检

TypeError:无法使用拦截器读取 Angular 中未定义的属性“数据”

SpringBoot------自定义拦截器