繁体   English   中英

角度使用全局拦截器

[英]Angular use global interceptor

我想全局使用2个拦截器(httpInterceptorProviders,jwtInterceptorProviders)但它在我的懒惰模块中不起作用。 我有CoreModule和X懒惰加载模块。 奇怪的是,我有一个swagger生成器(http服务)自动生成的代码,这个调用被拦截但是当我使用自定义http服务拦截器时不拦截这个请求。

Index.ts我获得提供者

/** Http interceptor providers in outside-in order */
export const httpInterceptorProviders = [
    { provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true }
];

export const jwtInterceptorProviders = [
    { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }
];

CoreModule,我在提供者中导入我的拦截器

@NgModule({
  imports: [
    // angular
    CommonModule,
    HttpClientModule,
    // ngrx
    StoreModule.forRoot(reducers, { metaReducers }),
    StoreRouterConnectingModule.forRoot(),
    EffectsModule.forRoot([AuthEffects, GoogleAnalyticsEffects]),
    environment.production
      ? []
      : StoreDevtoolsModule.instrument({
          name: "Angular NgRx Material Starter"
        }),

    // 3rd party
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    }),
    ApiModule.forRoot(() => {
      return new Configuration({
        basePath: `${environment.HOST}:${environment.PORT}`,
        apiKeys: { Authorization: "" }
      });
    })
  ],
  declarations: [],
  providers: [
    LocalStorageService,
    AuthGuardService,
    AnimationsService,
    TitleService,

    // retryHttpInterceptorProviders,
    { provide: ErrorHandler, useClass: AppErrorHandler },
    httpInterceptorProviders,
    jwtInterceptorProviders,
    { provide: RouterStateSerializer, useClass: CustomSerializer },
    {
      provide: HAMMER_LOADER,
      useValue: () => new Promise(() => {})
    },
    AnalyticsService,
    LayoutService,
    StateService,
    PetsServiceWithUpload
  ],
  exports: [TranslateModule]
})
export class CoreModule {
  constructor(
    @Optional()
    @SkipSelf()
    parentModule: CoreModule
  ) {
    if (parentModule) {
      throw new Error("CoreModule is already loaded. Import only in AppModule");
    }
  }
}

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(
    http,
    `${environment.i18nPrefix}/assets/i18n/`,
    ".json"
  );
}

的AppModule

@NgModule({
  declarations: [AppComponent, NavigationComponent, ErrorsComponent],
  imports: [
    BrowserAnimationsModule,
    BrowserModule,
    SharedModule,
    AppRoutingModule,
    AuthModule,
    ThemeModule.forRoot(),
    CoreModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

拦截器

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
    private isRefreshing = false;
    private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
    constructor(private injector: Injector,
        private localstorage: LocalStorageService,
        private authService: AuthService,
        private store: Store<AppState>, ) { }

    intercept(
        request: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        const tokenInfo = this.localstorage.getItem(AUTH_KEY);
        if (tokenInfo) {
            request = this.addToken(request, tokenInfo.token);
        }
        console.log('TCL: JwtInterceptor -> request', request);
        return next.handle(request).pipe(catchError(error => {
            if (error instanceof HttpErrorResponse && error.status === 401) {
                return this.handle401Error(request, next);
            } else {
                return throwError(error);
            }
        }));
    }

    private addToken(request: HttpRequest<any>, token: string): HttpRequest<any> {
        return request.clone({
            setHeaders: {
                'Authorization': `Bearer ${token}`
            }
        });
    }

    private handle401Error(request: HttpRequest<any>, next: HttpHandler) {

        if (!this.isRefreshing) {
            this.isRefreshing = true;
            this.refreshTokenSubject.next(null);
            const tokenInfo = this.localstorage.getItem(AUTH_KEY);
            return this.authService.authRefreshtokenPost({ refreshToken: tokenInfo.refreshToken }).pipe(
                switchMap((tokenRes: any) => {
                    this.isRefreshing = false;
                    this.refreshTokenSubject.next(tokenRes.token);
                    this.localstorage.setItem(AUTH_KEY,
                        { token: tokenRes.token, refreshToken: tokenRes.refreshToken, isAuthenticated: true });
                    return next.handle(this.addToken(request, tokenRes.token));
                }), catchError((error) => {
                    console.log('TCL: JwtInterceptor -> privatehandle401Error -> error', error);
                    this.store.dispatch(new AuthActions.Logout({ refreshToken: tokenInfo.refreshToken }));
                    return next.handle(request);
                }));

        } else {
            return this.refreshTokenSubject.pipe(
                filter(token => token != null),
                take(1),
                switchMap(jwt => {
                    return next.handle(this.addToken(request, jwt));
                }));
        }
    }
}

延迟加载模块

@NgModule({
  imports: [
    ThemeModule,
    PetsRoutingModule,
    StoreModule.forFeature("pets", petsReducer),
    TranslateModule.forChild({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      },
      isolate: true
    }),
    EffectsModule.forFeature([PetsEffects]),
    InfiniteScrollModule,
    SharedModule
  ],
  declarations: [
    PetsComponent,
    CreatePetComponent,
    ViewPetComponent,
    FormPetComponent,
    EditPetComponent,
    PetListVirtualComponent
  ],
  providers: []
})
export class PetsModule {}

如果我在petsModule中导出我的2个拦截器,它会拦截请求,但我只想在核心模块中导入一次。 我查看了这个stackblitz https://stackblitz.com/edit/angular-http-interceptor-working-for-lazy-loaded-module?file=src/app/core/token-interceptor.service.ts ,我确保我只在我的核心模块中导入HttpClientModule。

对于全局使用拦截器而且提供者在核心模块中应该在拦截器顶部添加@Injectable({providedIn:'root'}),如https://stackblitz.com/edit/angular-http-interceptor-working-for -lazy加载模块?文件= SRC /应用/核心/令牌interceptor.service.ts

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM