提問:呼叫 API 的時候需要帶 token 給後端驗證該怎麼辦?
我們可以使用 HttpInterceptor
進行統一處理!
HttpInterceptor
是用來攔截和處理 HTTP
請求與回應的機制,屬於 Angular HTTPClient module
的一部分。
通常會使用到的情況如下:
- 錯誤處理:
當發生HTTP
錯誤時,可以使用HttpInterceptor
來統一處理錯誤響應,例如顯示錯誤消息、重新導頁到登錄頁面等等。Request
和Response
的修改:
可以在HttpInterceptor
中對Request
和Response
進行修改,例如轉換Body
格式、添加Request Header
。- 記錄和監控:
在測試或監控的情境中,可以使用HttpInterceptor
來記錄所有請求和響應,方便追蹤問題或進行性能分析。
HttpInterceptor
的優點是,它可以幫我們集中處理HTTP Request
和Response
的共用邏輯,減少重複程式碼,增加維護性。不過缺點是它會讓Request
和Response
的流程變得複雜,尤其是在使用多個HttpInterceptor
的情況下。
官方提供了兩種 HttpInterceptor
的實作方式:functional
和 DI-based
。
首先我們講講 functional
的方式,這非常簡單,我們只需要 export
一個 function
,傳入的參數是 req
和 next
,回傳型別則是 Observable<HttpEvent<unknown>>
。
接著,在裡面加入我們需要修改的邏輯。以範例來說,我們要在 header
中加入 token。
req
:原始的HTTP
請求對象,類型為HttpRequest
。你可以從這個對象中獲取請求的 URL、標頭、主體等信息。
next
:一個HttpHandler
,它是請求處理鏈的一部分。你需要通過next.handle(req)
將請求傳遞到下一個攔截器或最終的HTTP
請求處理。
export function tokenInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {
const modifiedReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer your-token')
});
return next.handle(modifiedReq);
}
接著,只需要在 app.config.ts
的 providers
中使用 withInterceptors
這個 method
,就大功告成了!
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
withInterceptors([tokenInterceptor]),
)
],
};
DI-based
的實作方式稍微比 functional
的複雜一些,但基本概念是一樣的。我們創建一個可以被注入的 class
並且實作 HttpInterceptor
介面。HttpInterceptor
介面中定義了 intercept
的 method
。
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const modifiedReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer your-token')
});
return next.handle(modifiedReq);
}
}
接著在 app.config.ts
的 providers
中使用 withInterceptorsFromDi
這個 method
,並在下方用 HTTP_INTERCEPTORS
Token 來註冊我們創建的 Interceptor
。
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
// DI-based
withInterceptorsFromDi(),
),
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
],
};
token
用來告訴 Angular
這個 provider
是用來進行 HTTP
攔截的,useClass
則是告訴 Angular
要實作的 class
是哪一個,multi
則是代表可以有多個 HttpInterceptor
。
到這邊,我們的 HttpInterceptor
實作就告一段落了!下一篇文章我們會分享商城購物車的實作!