angular10教程之http 拦截器

Fork Me On Github

请求拦截器

登录令牌注入

token.interceptor.ts

ts
                        
@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  constructor(private injector: Injector) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const auth = this.injector.get(AuthService);
    const clonedRequest = request.clone({
      headers: auth.getTokenHeader(request),
      url: this.fixUrl(request.url),
      params: request.params
    });
    return next.handle(clonedRequest);
  }

  private fixUrl(url: string) {
    if (url.indexOf('http://') >= 0 || url.indexOf('https://') >= 0) {
      return url;
    }
    return environment.apiEndpoint + url;
  }
}

123456789101112131415161718192021222324

响应拦截器

例如登录令牌失效

reponse.interceptor.ts

ts
                   
@Injectable()
export class ResponseInterceptor implements HttpInterceptor {

  constructor(private injector: Injector) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    return next.handle(req).pipe(catchError((event: HttpEvent<any>) => {
      if (event instanceof HttpErrorResponse) {
        if (event.status === 401) {
          const auth = this.injector.get(AuthService);
          auth.logoutUser();
        }
      }
      return throwError(event);
    }));

  }
}
12345678910111213141516171819

使用

ts
             
@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },   // 使用请求拦截器
    { provide: HTTP_INTERCEPTORS, useClass: ResponseInterceptor, multi: true }, // 使用响应拦截器
  ],
})
export class ThemeModule {
  static forRoot(): ModuleWithProviders<ThemeModule> {
    return {
      ngModule: ThemeModule
    };
  }
}
12345678910111213

AuthService

ts
                                                      
const USER_KEY = 'user';

@Injectable()
export class AuthService {

  constructor(
    private http: HttpClient,
    @Inject(PLATFORM_ID) private platformId: any) {}

  /**
   * 清除本地的token
   */
  public logoutUser() {
    if (isPlatformBrowser(this.platformId)) {
      localStorage.clear();
    }
    this.store.dispatch(this.actions.logoutSuccess());
  }

  /**
   * 生成请求头
   * @returns HttpHeaders
   */
  getTokenHeader(request: HttpRequest<any>): HttpHeaders {
    if (this.getUserToken()) {
      return new HttpHeaders({
        'Content-Type': 'application/vnd.api+json',
        Authorization: `Bearer ${this.getUserToken()}`,
        Accept: '*/*'
      });
    }
    return new HttpHeaders({
      'Content-Type': 'application/vnd.api+json',
      Accept: '*/*'
    });
  }

  private setTokenInLocalStorage(user: any, keyName: string): void {
    const jsonData = JSON.stringify(user);
    if (isPlatformBrowser(this.platformId)) {
      localStorage.setItem(keyName, jsonData);
    }
  }

  public getUserToken() {
    if (isPlatformBrowser(this.platformId)) {
      const user: IUser = JSON.parse(localStorage.getItem(USER_KEY));
      return user ? user.token : null;
    } else {
      return null;
    }
  }
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
点击查看全文
标签: angular
0 491 0
在 angular 项目中实现对页面的访问控制
按下回车键,焦点移动到下一个表单或提交表单
使用ng-template 显示tree结构数据
使用 ViewContainerRef.createComponent 替代 ComponentFactoryResolver
angular 12使用 KaTex 显示 AsciiMath 格式的公式