首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular 4.3拦截器-如何使用?

Angular 4.3拦截器-如何使用?
EN

Stack Overflow用户
提问于 2017-07-28 00:00:27
回答 3查看 9.2K关注 0票数 8

我正在构建一个需要授权头的新应用程序。通常,我使用的方法与此scotch.io article中的方法非常相似。但我注意到,现在通过新的HttpClientModule在Angular 4生态系统中完全支持HTTP拦截器,我正在努力寻找一些关于如何使用它们的文档。

如果我是不正确的(从4.3开始),这是注入授权头的最佳实践,我也愿意接受建议。我的想法是,这是最近添加的一个功能,这意味着可能有很好的理由迁移到"Angular Approved“方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-28 09:02:48

这个答案是从CodeWarrior链接的official documentation中借用。

Angular允许您创建HttpInterceptor:

代码语言:javascript
复制
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);
  }
}

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

代码语言:javascript
复制
import {NgModule} from '@angular/core';
import {HTTP_INTERCEPTORS} from '@angular/common/http';

@NgModule({
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: NoopInterceptor,
    multi: true,
  }],
})
export class AppModule {}

要添加authorization header,您可以使用更改后的header克隆请求:

代码语言:javascript
复制
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);
  }
}

请注意,拦截器的行为类似于链,因此您可以设置多个拦截器来执行不同的任务。

票数 10
EN

Stack Overflow用户

发布于 2018-01-29 23:40:05

将AuthService注入拦截器的构造函数会给我带来这个错误:

未捕获错误:提供程序解析错误:无法实例化循环依赖项!InjectionToken_HTTP_INTERCEPTORS ("ERROR ->"):in NgModule AppModule in ./AppModule@-1:-1

因此,我没有将其注入到构造函数中,而是使用了@angular/coreInjector,它工作得很好。我将令牌存储在localStorage中,并使用基本身份验证。我需要设置

代码语言:javascript
复制
Authorization: 'Bearer token_string'

我是如何实现的:

token.interceptor.ts

代码语言:javascript
复制
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令牌字符串。

代码语言:javascript
复制
/**
 * Get jwt token
 * @returns {string}
 */
getToken(): string {
    return localStorage.getItem('token');
}

app.module.ts

导入TokenInterceptor

代码语言:javascript
复制
import {TokenInterceptor} from './pathToTheFile/token.interceptor';

providers:数组中的@NgModule下添加以下内容。

代码语言:javascript
复制
providers: [
    {
        provide: HTTP_INTERCEPTORS,
        useClass: TokenInterceptor,
        multi: true
    }
    //, other providers
]
票数 3
EN

Stack Overflow用户

发布于 2018-07-23 20:10:00

我推荐的方法的问题是,拦截器必须在编译时知道,而且显然都在同一个模块中。

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

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

代码语言:javascript
复制
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);
    }
}

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

代码语言:javascript
复制
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;
    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45355763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档