分类目录

链接

2020 年 4 月
 12345
6789101112
13141516171819
20212223242526
27282930  

近期文章

热门标签

新人福利,免费薅羊毛

现在位置:    首页 > Angular > 正文
Angular异步HTTP拦截器(HTTPInterceptor)
Angular 暂无评论 阅读(287)

Angular 附带的HttpClient API 接口是该API中最有用的功能,其中最重要的功能之一HttpInterceptor(HTTP拦截器,它使我们能够全局地拦截和转换HTTP请求。拦截器早已在AngularJS中提供,它们对于诸如身份验证之类的东西特别有用,在身份验证中,通常需要在每个请求中包含一个auth令牌。

在之前,HttpInterceptor我们将为Angular的内置HttpModule应用创建一个包装服务,我们的应用程序将与之交互,而不是HttpModule直接调用方法。一切都感觉有些麻烦。

现在,我们可以HttpClientModule直接使用拦截器作为管道中的中间件。干净整洁。

最近的项目中用到了Http Interceptor但是遇到了问题。当APP发出HTTP请求时,该请求必须包含token令牌才能正确进行身份验证,但是token令牌仅可从异步获取(首次或失效时)。这意味着我需要以某种方式暂停HTTP请求,直到token令牌可用为止。

对我来说,如何实现这一目标并不是立即显而易见的,而且官方也没有有用的文档。所以我想我将其记录在这里。也许对其他人会有帮助。

注意:本教程仅侧重于创建HttpInterceptor适合现有项目的异步

 一、增加 http interceptor

  1. import { Injectable } from "@angular/core";
  2. import {
  3.   HttpRequest,
  4.   HttpHandler,
  5.   HttpEvent,
  6.   HttpInterceptor,
  7.   HTTP_INTERCEPTORS,
  8. } from "@angular/common/http";
  9. import { Observable } from "rxjs";
  10. import { map, mergeMap } from "rxjs/operators";
  11. import { TokenService } from "src/app/core/services/token.service";
  12. import { IToken } from "../model/IToken";
  13.  
  14. const TOKEN_HEADER_KEY = "Authorization";
  15.  
  16. //auto add token to header for http request
  17. @Injectable()
  18. export class AuthInterceptor implements HttpInterceptor {
  19.   constructor(private tokenService: TokenService) {}
  20.  
  21.   intercept(
  22.     request: HttpRequest<any>,
  23.     next: HttpHandler
  24.   ): Observable<HttpEvent<any>> {
  25.     //skip token url
  26.  
  27.     if (request.url.indexOf("token") == -1) {
  28.       return this.tokenService.getToken().pipe(
  29.         mergeMap((res) => {
  30.           console.log(res);
  31.           let token = res as IToken;
  32.           //sessionStorage.setItem('token', token.token);
  33.           request = request.clone({
  34.             headers: request.headers.set(
  35.               TOKEN_HEADER_KEY,
  36.               "Bearer " + token.token
  37.             ),
  38.           });
  39.           return next.handle(request);
  40.         })
  41.       );
  42.     } else {
  43.       return next.handle(request);
  44.     }
  45.   }
  46. }
  47.  
  48. export const authInterceptorProviders = [
  49.   { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
  50. ];

二、tokenService (从sessionStorage中获取token,当token失效时,从Http中获取)

  1. import{Injectable} from "@angular/core";
  2. import{JwtHelperService} from "@auth0/angular-jwt";
  3. import{HttpClient,HttpHeaders} from "@angular/common/http";
  4. import{ environment } from "../../../environments/environment";
  5. import{IToken} from "src/app/shared/model/IToken";
  6. import{Observable, of } from "rxjs";
  7. const helper =newJwtHelperService();
  8. @Injectable({
  9.   providedIn:"root",
  10. })
  11. exportclassTokenService{
  12.   constructor(private http:HttpClient){}
  13. //getToken
  14. public getToken():Observable<object>{
  15.     let token = sessionStorage.getItem("token");
  16. if(!token ||!helper.isTokenExpired(token)){
  17.       let data ={
  18.         client_id: environment.clientId,
  19.         client_secret: environment.clientSecret,
  20.         grant_type:"client_credentials",
  21. };
  22.       let res =this.http.post(environment.tokenUrl, data);
  23. return res;
  24. }else{
  25. return of({ token: token });
  26. }
  27. }
  28. }

三、在app.module中增加interceptor

  1. import { BrowserModule } from "@angular/platform-browser";
  2. import { NgModule } from "@angular/core";
  3. import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
  4.  
  5. import { AppRoutingModule } from "./app-routing.module";
  6. import { AppComponent } from "./app.component";
  7. import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
  8. import { authInterceptorProviders } from "./shared/interceptor/auth.interceptor";
  9.  
  10. @NgModule({
  11.   declarations: [AppComponent],
  12.   imports: [
  13.     BrowserModule,
  14.     AppRoutingModule,
  15.     ChatModule,
  16.     HttpClientModule,
  17.     MaterialModule,
  18.     BrowserAnimationsModule,
  19.   ],
  20.   providers: [authInterceptorProviders],
  21.   bootstrap: [AppComponent],
  22. })
  23. export class AppModule {}

============ 欢迎各位老板打赏~ ===========

本文版权归Bruce's Blog所有,转载引用请完整注明以下信息:
本文作者:Bruce
本文地址:Angular异步HTTP拦截器(HTTPInterceptor) | Bruce's Blog

发表评论

留言无头像?