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 
]