【问题标题】:Angular 11 Http Interceptor within a Service服务中的 Angular 11 Http 拦截器
【发布时间】:2022-12-04 22:35:54
【问题描述】:

我有一个角度应用程序,它有一个添加不记名令牌的 http 拦截器:

export class AuthorizeInterceptor implements HttpInterceptor {
  constructor(private authorize: AuthorizeService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.authorize.getAccessToken()
      .pipe(mergeMap(token => this.processRequestWithToken(token, req, next)));
  }

  // Checks if there is an access_token available in the authorize service
  // and adds it to the request in case it's targeted at the same origin as the
  // single page application.
  private processRequestWithToken(token: string | null, req: HttpRequest<any>, next: HttpHandler) {
    if (!!token && this.isSameOriginUrl(req)) {
      req = req.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    }

    return next.handle(req);
  }

  private isSameOriginUrl(req: any) {
    // It's an absolute url with the same origin.
    if (req.url.startsWith(`${window.location.origin}/`)) {
      return true;
    }

    // It's a protocol relative url with the same origin.
    // For example: //www.example.com/api/Products
    if (req.url.startsWith(`//${window.location.host}/`)) {
      return true;
    }

    // It's a relative url like /api/Products
    if (/^\/[^\/].*/.test(req.url)) {
      return true;
    }

    // It's an absolute or protocol relative url that
    // doesn't have the same origin.
    return false;
  }
}

当我从一个组件中进行直接的 http 调用时,这工作正常:

  constructor(
    http: HttpClient, 
    @Inject('BASE_URL') baseUrl: string,
    private _Activatedroute:ActivatedRoute, 
    private _CustomerService:CustomerService) { 
    this.id = parseInt(this._Activatedroute.snapshot.paramMap.get("id")!);

    http.get<CustomerBase>(baseUrl + 'customer/getCustomerById?id=' + this.id).subscribe({
      next: (data: CustomerBase) => {
        console.log(data);
      }
    }); 
    
  }

但我有一项服务想打电话

 ngOnInit(): void {
    //using a service might not have the headers since it isn't intercepted by the auth interceptor
    this._CustomerService.getCustomerById(this.id!).subscribe({

但这没有被拦截器拾取并且没有不记名令牌,因此它失败并显示 401 Unauthorized

我想我已经正确地添加到 app.module.ts

  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthorizeInterceptor, multi: true }
  ],

如何确保作为服务发送的 http 请求也被拦截器接收?

【问题讨论】:

  • 确保你只在 app.module.ts 中导入了 HttpClientModule,它会跟踪你项目中的所有调用。

标签: angular


【解决方案1】:

尝试使用更简单的方法来获取令牌,如下所示:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const access_token = localStorage.getItem('access_token');
    const authReq = req.clone({
      setHeaders: {
        Authorization: 'Bearer ' + access_token
      }
    });

    return next.handle(authReq);
  }
}

如果它工作正常,也许你的问题在AppModuleAuthorizeServiceCustomerService中定义。

1. 应用模块:

确保正确导入 HTTP_INTERCEPTORHttpClientModule

import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http";
...
imports: [HttpClientModule]
providers: [{
  provide: HTTP_INTERCEPTORS,
  useClass: AuthInterceptor,
  multi: true,
}]

2.客户服务

确保您正确使用 HttpClient:

import {HttpClient} from "@angular/common/http";
...
constructor(private http: HttpClient) {}
...
http.get(...).pipe();

不要像这样使用它:

import { HttpBackend, HttpClient } from '@angular/common/http';
...
constructor(private httpClient: HttpClient, handler: HttpBackend) {
  // if you use it in this way, you won't go through any interceptors
  this.http = new HttpClient(handler);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 2017-11-07
    • 2018-05-19
    • 2015-11-30
    • 2022-01-04
    • 1970-01-01
    • 2019-03-25
    • 2018-07-08
    相关资源
    最近更新 更多