web前端

angular拦截器

2022-10-18  本文已影响0人  姜治宇

1.首先新建一个拦截器jwt.interceptor.ts:

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpClient,
} from '@angular/common/http';
import { Observable, Subject } from 'rxjs';

import { debounceTime } from 'rxjs/operators';

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
  public refreshToken$: Subject<boolean> = new Subject();

  constructor(private http: HttpClient) {
    this.refreshToken$.pipe(debounceTime(1000 * 300)).subscribe((v) => {
      this.http.get(`/auth/refreshToken`).subscribe((res: any) => {
        if (res.Success) {
          localStorage.setItem('ACCESS_TOKEN', res.Data.refreshToken);
          localStorage.setItem(
            'ACCESS_TOKEN_EXPIRE',
            JSON.stringify({
              time: new Date().getTime(),
              expires: res.Data.refreshExpiresIn,
            })
          );
          console.log('更新token成功');
        } else {
          console.error('更新token失败');
        }
      });
    });
  }
  //请求拦截
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const token = localStorage.getItem('ACCESS_TOKEN');
    const authReq = req.clone({
      headers: req.headers
        .set('Authorization', `Bearer ${token}`)
        .set('token', `${token}`),
    });
    // 检查token是否过期,如果过期自动续签。
    const tokenTime = localStorage.getItem('ACCESS_TOKEN_EXPIRE');
    if (tokenTime && token) {
      const tempTokenTime = JSON.parse(tokenTime);
      if (Number(tempTokenTime.time) && Number(tempTokenTime.expires)) {
        if (
          new Date().getTime() - Number(tempTokenTime.time) >
          (Number(tempTokenTime.expires) * 1000) / 3
        ) {
          this.refreshToken$.next(true);
        }
      }
    }
    return next.handle(authReq);
  }
}

2.在app.module.ts里注入。
由于拦截器是 HttpClient 服务的可选依赖,所以你必须在提供 HttpClient 的同一个(或其各级父注入器)注入器中注册提供这些拦截器。由于在 AppModule 中导入了 HttpClientModule,因此本应用在其根注入器中提供了 HttpClient。所以同样要在 AppModule 中注册提供这些拦截器。


import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { JwtInterceptor } from './common/interceptor/jwt.interceptor';
 
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }],   // InterceptorA 注册语句
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor() {

  }
}
上一篇下一篇

猜你喜欢

热点阅读