代码之家  ›  专栏  ›  技术社区  ›  joshrathke

角度4.3拦截器-如何使用?

  •  8
  • joshrathke  · 技术社区  · 9 年前

    scotch.io article 但是我注意到,HTTP拦截器现在通过新的HttpClientModule在Angular 4生态系统中得到了完全支持,我正试图找到一些关于如何准确使用它们的文档。

    如果我在(截至4.3)这是注入授权头的最佳实践方面有错误,我也愿意接受建议。我的想法是,这是最近添加的一个功能,这意味着可能有很好的理由迁移到“角度批准”方法。

    3 回复  |  直到 9 年前
        1
  •  10
  •   ProgrammingLlama Raveena Sarda    9 年前

    这个答案是借用了 official documentation

    Angular允许您创建HttpInterceptor:

    import {Injectable} from '@angular/core';
    import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
    
    @Injectable()
    export class NoopInterceptor implements HttpInterceptor {
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req);
      }
    }
    

    然后你可以像这样将其集成到你的应用程序中:

    import {NgModule} from '@angular/core';
    import {HTTP_INTERCEPTORS} from '@angular/common/http';
    
    @NgModule({
      providers: [{
        provide: HTTP_INTERCEPTORS,
        useClass: NoopInterceptor,
        multi: true,
      }],
    })
    export class AppModule {}
    

    要添加授权标头,可以使用更改的标头克隆请求:

    import {Injectable} from '@angular/core';
    import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
    
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {
      constructor(private auth: AuthService) {}
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // Get the auth header from the service.
        const authHeader = this.auth.getAuthorizationHeader();
        // Clone the request to add the new header.
        const authReq = req.clone({headers: req.headers.set('Authorization', authHeader)});
        // Pass on the cloned request instead of the original request.
        return next.handle(authReq);
      }
    }
    

    注意,拦截器就像一个链,因此可以设置多个拦截器来执行不同的任务。

        2
  •  3
  •   Lahar Shah    8 年前

    附属国!InjectionToken\u HTTP\u拦截器(“[错误->]”):在里面 NgModule AppModule in/AppModule@-1:-1

    Injector 属于 @angular/core localStorage 并使用basic auth。我需要设置

    Authorization: 'Bearer token_string'
    

    以下是我如何实现的:

    令牌.interceptor.ts

    import {Injectable, Injector} from '@angular/core';
    
    import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
    import {Observable} from 'rxjs/Observable';
    import {AuthService} from './auth.service';
    
    @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);
            if (auth.getToken()) {
                request = request.clone({
                    setHeaders: {
                        Authorization: `Bearer ${auth.getToken()}`
                    }
                });
    
            }
    
            return next.handle(request);
        }
    }
    

    AuthService中的getToken函数

    在这里,您可以实现整个逻辑来获取报头或仅获取令牌。在我的例子中,我调用它只是为了获得JWT令牌字符串。

    /**
     * Get jwt token
     * @returns {string}
     */
    getToken(): string {
        return localStorage.getItem('token');
    }
    

    导入 TokenInterceptor

    import {TokenInterceptor} from './pathToTheFile/token.interceptor';
    

    @NgModule 在里面 providers:

    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: TokenInterceptor,
            multi: true
        }
        //, other providers
    ]
    
        3
  •  0
  •   dfl    8 年前

    我选择实现一个拦截器和一系列可以在运行时扩展的处理函数。服务的intercept方法负责next()逻辑。

    服务(基本代码,无验证或维护):

    export type HttpHandlerFunction = (req: HttpRequest<any>) => HttpRequest<any>;
    
    @Injectable()
    export class HttpInterceptorService implements HttpInterceptor {
        private _handlers: Array<HttpHandlerFunction> = [];
    
        addHandler(handler: HttpHandlerFunction): void {
            this._handlers.push(handler);
        }
    
        intercept(req: HttpRequest<any>, next: HttpHandler):
            Observable<HttpEvent<any>> {
                this._handlers.forEach((handler: HttpHandlerFunction) => {
                    req = handler(req);
                })
            return next.handle(req);
        }
    }
    

    以及在不同模块的某些服务中的用法:

    constructor(injector: Injector) {
    
        const interceptorsArray: Array<any> = injector.get(HTTP_INTERCEPTORS),
            interceptor: HttpInterceptorService = interceptorsArray &&
                interceptorsArray.filter((i: any) => i instanceof HttpInterceptorService)[0];
        if (interceptor) {
            interceptor.addHandler((req: HttpRequest<any>) => {
                const accessToken = this.getAccessToken();
                if (accessToken) {
                    // doesn't work with direct headers.set, you must clone
                    req = req.clone({ headers: req.headers.set('Authorization', accessToken) });
                }
            return req;
        });
    }
    
    推荐文章