2017-08-30 33 views
1

我正在嘗試在Angular 2應用程序中添加基於JWT的身份驗證。在Angular中配置全局身份驗證http頭的正確方法是什麼?

我從Auth0收到一個idToken並將其存儲在LocalStorage中。現在,我要確保,所有傳出的HTTP調用我的API都會有這樣的標題設置:

授權:承載e3rere ....

當然,我可以手動添加每個HTTP調用。但是一勞永逸地配置會更方便。

在Angular中做這件事的正確方法是什麼? (角2)

+1

其實Angular 2.x?如果你使用的是4.3或更高版本,你可以使用新的'HttpClient'並實現一個[攔截器](https://angular.io/guide/http#intercepting-all-requests-or-responses)。否則,通常會對'Http'或[請求選項]進行子類化(https://v2.angular.io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options)並使用DI來注入你自己的版本。這兩種方法已在別處記錄。 – jonrsharpe

+0

Thx @jonrsharpe我試着按照請求選項https://v2.angular提到的文章。io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options但是這些頭文件似乎並沒有像預期的那樣被添加。我現在嘗試使用其他地方提到的攔截器。 –

回答

0

我添加了一個方法,我AuthService,該處理創建頭

@Injectable() 
export class AuthenticationService { 

    //Other stuff your authentication service might do 

    getHeaderWithAuthorization() { 
     let currentUser = JSON.parse(localStorage.getItem('currentUser')); 
     if (currentUser && currentUser.Token) { 

      let headers = new Headers({ 'Content-Type': 'application/json' }); 
      headers.append('Authorization', 'Bearer ' + currentUser.Token); 
      return new RequestOptions({ headers: headers }); 
     } 
    } 
} 


@Injectable() 
export class UserService { 

    private baseUrl; 
    private options: RequestOptions; 

    constructor(private http: Http, private authService: AuthenticationService)    
{ 
     this.baseUrl = "/api/User/"; 
     this.options = authService.getHeaderWithAuthorization(); 
    } 

    SaveUser(user) { 
     return this.http.post(this.baseUrl + "SaveUser", user, this.options) 
      .map((res) => res.json()); 
    } 

} 
+0

Thx分享。但這是我試圖避免的一種情況,因爲我需要在我的所有服務中重複這些代碼。 –

0

方法1:

如果您使用的角度4.3+,那麼你就可以創建一個interceptor爲此將作爲中介。

注:爲了使用已經攔截使用的HttpClient代替Http服務,這是從角4.3新增加了,會給你some benefits通過HTTP服務。

如果有用戶登錄,您可以添加頁眉

@Injectable() 
export class AddHeaderInterceptor implements HttpInterceptor { 
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
     if(UserService.getToken()){ 
     req.headers.set('Authorization', 'Bearer ' + UserService.getToken()); 
     } 

     return next.handle(req); 
    } 
} 

重要提示:請不要忘記提供您的應用程序模塊中的攔截器類。

import {HTTP_INTERCEPTORS} from '@angular/common/http'; 

@NgModule({ 
    providers: [{ 
    provide: HTTP_INTERCEPTORS, 
    useClass: AddHeaderInterceptor, 
    multi: true, 
    }], 
}) 

方法2:

如果您使用的版本低於4.3.0,那麼你可以適應不同的做法類似延長BaseRequestOptions注入,通用報頭所有請求。

import {BaseRequestOptions} from '@angular/http'; 
    @Injectable() 
    export class AdddingHeaderOptions extends BaseRequestOptions { 
     constructor() { 
      super(); 
      if(UserService.getToken()){ 
       this.headers.append('X-Requested-With', 'XMLHttpRequest'); 
       this.headers.append('Authorization', 'Bearer ' + UserService.getToken()); 
      } 
     } 
    } 

現在,您可以將它提供給應用程序模塊文件。

@NgModule({ 
    providers : [ 
     {provide: RequestOptions, useClass: AdddingHeaderOptions } 
    ] 
}) 
+0

您應該注意,這隻適用於Angular的新版本;在4.3.0中引入了'@ angular/common/http',許多應用程序將使用'@ angular/http'。 – jonrsharpe

+0

哦,我明白了,在這種情況下,我認爲這可能是一個更大的變化。所以我會回過頭去用一個包裝類來代替。 –

0

我不確定這是否會被認爲是最佳解決方案,但我發現它非常有用。

我添加了這個功能app.module.ts:

export function authHttpServiceFactory(http: Http, options: RequestOptions, auth: AuthService) { 
    return new AuthHttp(new AuthConfig(
     { 
     tokenName: 'id_token', 
     globalHeaders: [{'Content-Type': 'application/json'}], 
     tokenGetter: (() => localStorage.getItem('id_token')) 
     } 
    ), http, options); 
} 
... 
providers: [...{ 
    provide: AuthHttp, 
    useFactory: authHttpServiceFactory, 
    deps: [ Http, RequestOptions, AuthService ] 
},...] 

,最後我想確保我的服務取決於AuthHttp而不是HTTP。

相關問題