6

我正在构建一个需要授权标题的新应用程序。通常我会使用与此scotch.io article中发现的方法非常相似的内容。但是现在我注意到HTTP拦截器现在已经通过新的HttpClientModule在Angular 4生态系统中得到了全面的支持,我正试图找到一些关于如何使用它们的文档。Angular 4.3拦截器 - 如何使用?

如果我不正确(截至4.3)这是注入授权标题的最佳做法,我也会接受建议。我的想法是,这是最近添加的功能,这意味着可能有充分的理由迁移到“角度批准”方法。

+0

http://blog.ninja-squad.com/2017/07/17/http-client-module/这似乎有用 – john

+0

您可以检查https://github.com/auth0/angular2-jwt /tree/v1.0 1.x分支为例。 – estus

+0

官方角度的文档是相当不错的:https://angular.io/guide/http#setting-new-headers – CodeWarrior

回答

6

此答案是从CodeWarrior链接的official documentation借用的。

角允许您创建一个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); 
    } 
} 

请注意,拦截器的行为像一个柴n,因此您可以设置多个拦截器来执行不同的任务。

+0

为什么是克隆?为什么不直接用'rew.headers.set'在'req'中直接设置标题? – DAG

+2

Dag,根据文档,头对象是不可变的,所以如果你想修改它,你必须克隆它。 – john

+0

角4.2.3是否一样? –

0

注射AuthService到拦截器的构造是给我这个错误:

Uncaught Error: Provider parse errors: Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule in ./[email protected]:-1

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

Authorization: 'Bearer token_string' 

下面是我已经实现:

token.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); 
    } 
} 

为gettoken功能AuthService

在这里,您可以实现整个逻辑来获取标题或仅标记。在我的情况下,我只调用它来获取JWT令牌字符串。

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

app.module.ts

导入TokenInterceptor

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

providers:阵列添加@NgModule在以下。

providers: [ 
    { 
     provide: HTTP_INTERCEPTORS, 
     useClass: TokenInterceptor, 
     multi: true 
    } 
    //, other providers 
]