哈囉大家好!
昨天分享了如何透過Angular Interceptor來更有效率的附加Authorization Header,今天要來分享如何處理Session Token過期時後端返回的HTTP error。
當前端送到後端的Session Token過期時,後端會回傳HTTP 401 Error(未授權錯誤)。在前端可以透過同一個JwtInterceptor來監聽response,並在接收到401錯誤時,將使用者強制登出,導回登入頁面。
為了要成功攔截API response中的錯誤,我們會使用RxJS中的catchError
operator:
import {
HttpErrorResponse,
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { catchError, Observable, throwError } from 'rxjs';
@Injectable()
export class jWTInterceptorInterceptor implements HttpInterceptor {
constructor(private route: Router) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// 從localStorage 取得session token
const authToken = localStorage.getItem('go_dutch_session_token');
const authReq: any = authToken
? req.clone({ setHeaders: { Authorization: `Bearer ${authToken}` } })
: req;
return next.handle(authReq).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
// 清除已過期的session token
localStorage.removeItem('go_dutch_session_token');
// 將user導回登入頁面
this.route.navigate(['/login']);
// return error, 讓component中的訂閱(subscription)知道請求失敗
return throwError(() => error);
}
// 非401錯誤,直接回傳error
return throwError(() => error);
})
);
}
}
之後在app.module.ts中導入路由模組(RouterModule):
...
import { RouterModule } from '@angular/router';
@NgModule({
declarations: [
AppComponent,
RecordsComponent,
NavbarComponent,
...
],
imports: [
BrowserModule,
AppRoutingModule,
SocialLoginModule,
LoginComponent,
HttpClientModule,
RouterModule.forRoot([]), // 導入路由模組
],