如何为 AngularJS 2 编写 http 拦截器?

问题描述 投票:0回答:2

我想从一个地方检查我的所有 http 响应。例如身份验证状态。如果响应说用户不再经过身份验证,我想重定向或其他东西。有什么办法可以做到吗?

angular angular2-http
2个回答
6
投票

我们来了

创建这样的服务

export const JWT_RESPONSE_HEADER = 'X-Auth-Token';

@Injectable()
export class AuthHttp extends Http {
  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
    super(backend, defaultOptions);
  }

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    const request = super.request(url, this.appendAuthHeader(options));
    request.map(this.saveToken);
    return request;
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    const request = super.get(url, this.appendAuthHeader(options));
    request.map(this.saveToken);
    return request;
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    const request = super.post(url, body, this.appendAuthHeader(options));
    request.map(this.saveToken);
    return request;
  }

  put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    const request = super.put(url, body, this.appendAuthHeader(options));
    request.subscribe(this.saveToken);
    return request;
  }

  delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    const request = super.delete(url, this.appendAuthHeader(options));
    request.map(this.saveToken);
    return request;
  }

  private appendAuthHeader(options?: RequestOptionsArgs): RequestOptionsArgs {
    let mergedOptions: RequestOptionsArgs;
    if (!options) {
      mergedOptions = { headers: new Headers() };
    } else {
      mergedOptions = options;
    }
    const token = localStorage.getItem(JWT_RESPONSE_HEADER);
    const isTokenSet = mergedOptions.headers.has('Authorization');
    if (token && !isTokenSet) mergedOptions.headers.append('Authorization', `Bearer ${token}`);
    return mergedOptions;
  }

  private saveToken(res: Response): void {
    const token = res.headers.get(JWT_RESPONSE_HEADER);
    if (token) localStorage.setItem(JWT_RESPONSE_HEADER, token);
  }
}

并将其包含在您的 app.module.ts 中,如下所示

@NgModule({
    imports: [
        BrowserModule,
        ContentModule,
        routing,
        HttpModule
    ],
    declarations: [
        AppComponent,
        LoginComponent
    ],
    providers: [
        appRoutingProviders,
        LoginService,
        {
            provide: Http,
            useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new AuthHttp(backend, defaultOptions),
            deps: [XHRBackend, RequestOptions]
        }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

您不必对使用 http 的其他服务进行任何更改

https://github.com/mtinner/CAS-FEE_Project2/blob/develop/src/frontend/components/common/authentication/auth-http.service.ts

https://github.com/mtinner/CAS-FEE_Project2/blob/ebab26fb8a8463cf9f65c3bc9e4d806d665bec7e/src/frontend/components/app.module.ts


0
投票

另外,从 Angular 4.3 版本开始,您可以使用

HttpInterceptor
。官方文档的更多信息在这里HttpInterceptor

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
 constructor(public auth: AuthService) {}

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
   request = request.clone({
     setHeaders: {Authorization: `Bearer ${this.auth.getToken()}`}
   });

   return next.handle(request);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.