用预检拦截HTTP请求,然后执行原始请求 [英] Intercepting HTTP request with a preflight, and then executing the original request

查看:89
本文介绍了用预检拦截HTTP请求,然后执行原始请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写以下Angular HTTP拦截器:

I'm trying to write the following Angular HTTP interceptor:

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
  if (request.url.endsWith('/csrf')) {
    return next.handle(request);
  }

  if (!this.cookieService.check('XSRF-TOKEN')) {
    const csrfRequest = new HttpRequest('GET', environment.apiUrl + '/csrf');

    return next.handle(csrfRequest).pipe(
      // something here to retry the original request?
    );
  }

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

  return next.handle(modifiedReq);
}

基本思想是,如果浏览器未设置 XSRF-TOKEN cookie,则我们需要先调用/csrf 来对请求进行预检设置该cookie.然后我们需要执行原始请求.

The basic idea is that if the browser doesn't have the XSRF-TOKEN cookie set, we need to preflight the request with a call to /csrf to first set that cookie. Then we need to do the original request.

如果未设置cookie,则上述拦截器确实会成功执行/csrf 调用.我正在努力的是在/csrf 调用之后如何也执行原始HTTP请求.

The above interceptor does successfully do the /csrf call if the cookie is not set. What I'm struggling with is how to also do the original HTTP request AFTER that /csrf call.

我觉得这可以通过可观察的管道实现,但是我没有很多可观察的知识,而看着RxJS文档让我更加困惑.

I feel like it can be achieved by observable piping, but I don't have a lot of observables knowledge and looking at the RxJS docs has left me even more confused.

推荐答案

您可以通过 HttpClient 在拦截器中执行此/csrf -request(应将其注入拦截器中))并将其转换为可观察到的修改后的请求处理程序.它看起来像:

You can perform this /csrf-request inside interceptor via HttpClient (it should be injected in interceptor) and transform it into modified request handler observable. It will look like:

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
  if (request.url.endsWith('/csrf')) {
    return next.handle(request);
  }
  
  return of(this.cookieService.check('XSRF-TOKEN'))
            .pipe(
                switchMap((hasToken: boolean): Observable<HttpEvent<unknown>> => {
                    if (hasToken) {
                        const modifiedReq = request.clone({
                          headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
                        });

                        return next.handle(modifiedReq); 
                    }
                    
                    return httpClient.get(environment.apiUrl + '/csrf')
                                .pipe(
                                    switchMap((): Observable<HttpEvent<unknown>> => {
                                        const modifiedReq = request.clone({
                                          headers: request.headers.set('X-XSRF-TOKEN', this.cookieService.get('XSRF-TOKEN')),
                                        });

                                        return next.handle(modifiedReq); 
                                    })
                                );
                })
            );
}

这篇关于用预检拦截HTTP请求,然后执行原始请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆