지속적인 로그인 없이 사용자 세션을 유지하는 것이 원활한 웹 경험의 핵심입니다. 이 블로그에서는 Angular에서 토큰 새로 고침 워크플로를 구현하여 401 오류를 처리하고 동시 요청을 효과적으로 관리하는 방법을 보여 드리겠습니다.
인증 시스템에서 액세스 토큰은 보안 위험을 최소화하기 위해 수명이 짧습니다. 액세스 토큰이 만료되면 새로 고침 토큰을 사용하면 사용자가 다시 로그인하지 않고도 애플리케이션이 서버에서 새 액세스 토큰을 요청할 수 있습니다.
Angular의 HttpInterceptor를 사용하여 새로 고침 토큰 메커니즘을 구현하겠습니다. 목표는 승인되지 않은 요청(401 오류)을 차단하고 원래 요청을 다시 시도하기 전에 토큰을 새로 고치는 것입니다.
차단 요청:
인터셉터가 401 Unauthorized 응답을 감지합니다.
토큰 새로 고침:
토큰이 만료되면 RefreshToken은 새 토큰을 가져옵니다.
재시도 요청:
원래 요청이 새 토큰으로 재시도됩니다.
대기열 관리:
보류 중인 요청은 토큰이 새로 고쳐지면 처리됩니다.
handleUnauthorized( req: HttpRequest<any>, next: HttpHandlerFn ): Observable<any> { if (!this.isRefreshingToken) { this.isRefreshingToken = true; // Notify all waiting requests that the token is being refreshed this.tokenSubject.next(null); return this.refreshToken().pipe( switchMap((newToken: string) => { if (newToken) { this.tokenSubject.next(newToken); // Retry the original request with the new token return next(this.addToken(req, newToken)); } // If token refresh fails, log out the user this.logout(); return throwError(() => 'Token expired'); }), catchError((error) => { this.logout(); // Log out on error return throwError(() => error); }), finalize(() => { this.isRefreshingToken = false; // Reset the flag }), ); } else { // Queue requests while a token is being refreshed return this.tokenSubject.pipe( filter((token) => token != null), take(1), switchMap((token) => next(this.addToken(req, token))), ); } }
handleUnauthorized 함수는 HTTP 요청이 액세스 토큰이 만료되었거나 유효하지 않음을 나타내는 401 Unauthorized 상태를 수신하는 시나리오를 관리하도록 설계되었습니다. 이 기능을 사용하면 애플리케이션이 토큰을 새로 고치고 실패한 요청을 원활하게 재시도할 수 있습니다.
handleUnauthorized( req: HttpRequest<any>, next: HttpHandlerFn ): Observable<any> { if (!this.isRefreshingToken) { this.isRefreshingToken = true; // Notify all waiting requests that the token is being refreshed this.tokenSubject.next(null); return this.refreshToken().pipe( switchMap((newToken: string) => { if (newToken) { this.tokenSubject.next(newToken); // Retry the original request with the new token return next(this.addToken(req, newToken)); } // If token refresh fails, log out the user this.logout(); return throwError(() => 'Token expired'); }), catchError((error) => { this.logout(); // Log out on error return throwError(() => error); }), finalize(() => { this.isRefreshingToken = false; // Reset the flag }), ); } else { // Queue requests while a token is being refreshed return this.tokenSubject.pipe( filter((token) => token != null), take(1), switchMap((token) => next(this.addToken(req, token))), ); } }
if (!this.isRefreshingToken) { this.isRefreshingToken = true; this.tokenSubject.next(null);
return this.refreshToken(url).pipe( switchMap((newToken: string) => { if (newToken) { this.tokenSubject.next(newToken); return next(this.addToken(req, newToken)); } this.logout(); return throwError(() => 'Token expired'); }),
return this.tokenSubject.pipe( filter((token) => token != null), // Wait for a non-null token take(1), // Only take the first emitted token switchMap((token) => next(this.addToken(req, token))), );
catchError((error) => { this.logout(); return throwError(() => error); }),
요청에 토큰 추가
addToken 메소드는 나가는 요청의 헤더에 새 토큰을 추가합니다.
finalize(() => { this.isRefreshingToken = false; }),
HttpInterceptor는 이 워크플로를 구현하기에 완벽한 장소입니다. 이를 통해 개별 서비스 호출을 수정하지 않고도 모든 HTTP 요청을 가로채고 전역적으로 토큰 관리를 처리할 수 있습니다.
addToken(request: HttpRequest<any>, token: string): HttpRequest<any> { return request.clone({ setHeaders: { 'X-Token': token, }, }); }
요약하자면 견고한 토큰 새로 고침 워크플로는 Angular 애플리케이션에서 원활한 사용자 경험과 안전한 세션 관리를 보장합니다. 401 오류를 효과적으로 처리하고 동시 요청을 관리함으로써 안정성을 유지하고 사용자를 만족시킬 수 있습니다. 읽어주셔서 감사합니다. 아래에 의견이나 질문을 자유롭게 공유해 주세요!
위 내용은 Angular의 토큰 새로 고침의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!