哈囉大家好!
昨天分享了在ApiService中建立CreateAuthHeader() function來回傳Authorization Header, 並且在其它API中呼叫,在發送請求時附加上。
雖然只需要在API中添加const headers = this.createAuthHeaders();
這行程式碼,但若之後應用程式規模變大,每次手動添加Header就會變得沒有效率。
在Angular中,有一個工具-攔截器(Interceptor)可以幫助我們解決每次都需要手動添加Header的問題!
Interceptor可以自動攔截所有發送到後端的HTTP請求,並將Session Token附加到所有發送到後端的請求。
要讓interceptor幫我們自動添加Authorization header,需要完成兩個任務:建立interceptor class,還有更新Angular應用的主要module。
首先透過指令建立一個新的Interceptor class:
ng g interceptor interceptors/JWT_interceptor
這個class會檢查每個發送的請求,如果請求中有token, 就會修改請求中的headers。
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export class jWTInterceptorInterceptor implements HttpInterceptor {
constructor() {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// 從localStorage 取得session token
const authToken = localStorage.getItem('go_dutch_session_token');
if (authToken) {
// 這裡必須要複製請求(因為request object不可變)+修改Header
const clonedrequest = req.clone({
setHeaders: {
Authorization: `Bearer ${authToken}`,
},
});
// 發送改好的請求
return next.handle(clonedrequest);
}
// 沒有token,直接發送原請求
return next.handle(req);
}
}
要讓Angular知道要使用這個interceptor,我們必須在app.module.ts中註冊,在providers中新增interceptor的配置:
providers: [
{
id: GoogleLoginProvider.PROVIDER_ID,
provider: new GoogleLoginProvider(
environment.googleOAuthClientId,
{}
),
},
// 註冊interceptor
{
provide: HTTP_INTERCEPTORS,
useClass: jWTInterceptorInterceptor,
multi: true, // 允許註冊多個interceptor
},
]
原本的ApiService就不需要手動處理header,可以移除CreateAuthHeaders() function,直接發送請求:
getAllUsers() {
const url = `${environment.apiBaseUrl}/Users/all-users`;
return this.http.get(url);
}
修改好之後,所有發送到後端的請求都會自動附帶Session Token,只要Token有效,後端的[Authorize]屬性就可以順利通過驗證,讓程式碼更乾淨,處理也更方便了