> 웹 프론트엔드 > JS 튜토리얼 > Angular의 토큰 새로 고침

Angular의 토큰 새로 고침

Patricia Arquette
풀어 주다: 2024-12-31 20:10:13
원래의
507명이 탐색했습니다.

지속적인 로그인 없이 사용자 세션을 유지하는 것이 원활한 웹 경험의 핵심입니다. 이 블로그에서는 Angular에서 토큰 새로 고침 워크플로를 구현하여 401 오류를 처리하고 동시 요청을 효과적으로 관리하는 방법을 보여 드리겠습니다.


새로 고침 토큰 워크플로란 무엇입니까?

인증 시스템에서 액세스 토큰은 보안 위험을 최소화하기 위해 수명이 짧습니다. 액세스 토큰이 만료되면 새로 고침 토큰을 사용하면 사용자가 다시 로그인하지 않고도 애플리케이션이 서버에서 새 액세스 토큰을 요청할 수 있습니다.


각도 구현

Angular의 HttpInterceptor를 사용하여 새로 고침 토큰 메커니즘을 구현하겠습니다. 목표는 승인되지 않은 요청(401 오류)을 차단하고 원래 요청을 다시 시도하기 전에 토큰을 새로 고치는 것입니다.


완전한 작업 흐름

  • 차단 요청:
    인터셉터가 401 Unauthorized 응답을 감지합니다.

  • 토큰 새로 고침:
    토큰이 만료되면 RefreshToken은 새 토큰을 가져옵니다.

  • 재시도 요청:
    원래 요청이 새 토큰으로 재시도됩니다.

  • 대기열 관리:
    보류 중인 요청은 토큰이 새로 고쳐지면 처리됩니다.

Refresh Token in Angular


코드 개요

  1. 토큰 새로고침 로직 handlerUnauthorized 메소드는 만료된 토큰으로 인해 요청이 실패하는 경우 토큰 새로 고침을 처리합니다.
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 상태를 수신하는 시나리오를 관리하도록 설계되었습니다. 이 기능을 사용하면 애플리케이션이 토큰을 새로 고치고 실패한 요청을 원활하게 재시도할 수 있습니다.

  1. 여러 새로 고침 요청 방지 이 함수는 isRefreshingToken 플래그를 사용하여 한 번에 하나의 토큰 새로 고침 요청만 이루어지도록 합니다. 토큰이 이미 새로 고쳐지고 있는 경우 새 토큰을 사용할 수 있을 때까지 후속 요청이 대기열에 추가됩니다.
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))),
    );
  }
}
로그인 후 복사
로그인 후 복사
  1. 토큰 새로고침 진행 중인 새로 고침 요청이 없으면 RefreshToken 메서드를 사용하여 토큰 새로 고침을 시작합니다. 새 토큰을 받은 후:
  • tokenSubject에 저장됩니다.
  • 업데이트된 토큰을 사용하여 원래 요청이 재시도됩니다.
if (!this.isRefreshingToken) {
  this.isRefreshingToken = true;
  this.tokenSubject.next(null);

로그인 후 복사
  1. 동시 요청 처리 토큰 새로 고침이 이미 진행 중인 경우 함수는 후속 요청을 대기열에 넣습니다. 이러한 요청은 진행하기 전에 tokenSubject가 새 토큰을 내보낼 때까지 기다립니다.
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');
  }),

로그인 후 복사
  1. 오류 처리 토큰 새로 고침이 실패하거나 예외가 발생하는 경우:
  • 사용자가 로그아웃되었습니다.
  • 발신자에게 오류가 반환됩니다.
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))),
);
로그인 후 복사
  1. 정리 finalize 연산자는 isRefreshingToken 플래그가 재설정되어 후속 새로 고침 요청을 허용하도록 합니다.
catchError((error) => {
  this.logout();
  return throwError(() => error);
}),

로그인 후 복사

요청에 토큰 추가
addToken 메소드는 나가는 요청의 헤더에 새 토큰을 추가합니다.

finalize(() => {
  this.isRefreshingToken = false;
}),
로그인 후 복사

Angular HTTP 인터셉터에서 사용하기

HttpInterceptor는 이 워크플로를 구현하기에 완벽한 장소입니다. 이를 통해 개별 서비스 호출을 수정하지 않고도 모든 HTTP 요청을 가로채고 전역적으로 토큰 관리를 처리할 수 있습니다.

addToken(request: HttpRequest<any>, token: string): HttpRequest<any> {
  return request.clone({
    setHeaders: {
      'X-Token': token,
    },
  });
}
로그인 후 복사

요약하자면 견고한 토큰 새로 고침 워크플로는 Angular 애플리케이션에서 원활한 사용자 경험과 안전한 세션 관리를 보장합니다. 401 오류를 효과적으로 처리하고 동시 요청을 관리함으로써 안정성을 유지하고 사용자를 만족시킬 수 있습니다. 읽어주셔서 감사합니다. 아래에 의견이나 질문을 자유롭게 공유해 주세요!

위 내용은 Angular의 토큰 새로 고침의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿