当角度令牌过期时如何重定向到注销?

问题描述 投票:0回答:2

我有一个 Angular 13 应用程序。我在那里使用 JWT 令牌进行身份验证。一切正常。但我给 JWT 令牌的令牌过期时间是 1 小时。一旦服务器端的令牌过期,我想从前端应用程序中注销用户。

我这样做了,但似乎有问题并且对我不起作用:

export class authInterceptor implements HttpInterceptor {

  constructor(private userService: UserService) {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.userService.isAuthentificated()) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${this.userService.getToken()}`
        }
      });
    }
    return next.handle(request).pipe(
      tap(event => {
      }, error => {
        this.onSubscribeError(error);
      })
    );
  }

  private onSubscribeError(error: any): void {
    if (error.status === 401 || error.status === 403) {
      this.userService.logout();
    }
  }
}

任何人都可以告诉我我做错了什么并帮助我改正吗?

angular jwt angular-http-interceptors
2个回答
1
投票

E. Maggini 提供的链接从技术上来说很好,但至少接受的答案仅与让服务器决定它是否过期有关。

如果您没有调用服务器并收到 401,您的 UI 将保持登录状态,直到您这样做为止。

你需要两者的结合;添加到您的拦截器中以检查您的 401 并注销您(当然),并且应用程序本身会检查令牌。

最简单的方法就是在旅途中留出一段时间检查令牌是否过期。

假设您有某种具有基本登录/注销处理功能的单例

AuthService
...

@Injectable()
export class AuthService {
    private jwt: string;
    private expiryTimer: any;

    public login(jwt: string): void {
        this.jwt = jwt;
        this.expiryTimer = setInterval(() => { this.checkExpiry(); }, 60000);
        this.router.navigate(['...']);
    }

    public logout(): void {
        this.jwt = undefined;
        if (this.expiryTimer) clearInterval(this.expiryTimer);
        this.router.navigate(['...']);
    }

    private checkExpiry(): void {
        if (this.jwtService.hasExpired(this.jwt)) this.logout();
    }
}

假设您有一些 jwt 服务或方法或其他东西来检查过期时间...

它看起来会比这更复杂,因为据推测,您实际上会将令牌存储在某个地方(本地存储?),以便处理页面刷新等。

但基础知识就在那里 - 不要想太多,它就像每隔 x 检查一次令牌(1m 足够好吗?)一样简单,如果它过期,则注销...

您修改后的拦截器将使用相同的东西;得到 401 吗?

this.authService.logout();
。完成。


0
投票
// Create HttpInterceptor class like yours and follow the steps as mentioned
@Injectable()
export class JwtInterceptor implements HttpInterceptor {

  // Inject your AuthService
  constructor(private authService: AuthService) { }

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    
    // Find your login response from authService
    const loginResponse = this.authService.getLoginResponse()

    // Check loginResponse?.token has any token
    if (loginResponse?.token) {
        
      // Check expire time coming from server response
      let tokenExpirationDate: any = new Date(loginResponse?.expiresAt);

      if ((tokenExpirationDate > new Date())) {
        request = request.clone({
          setHeaders: {
            Authorization: `Bearer ${loginResponse.token}`
          }
        });
      }
      else {
        // Call logout
        this.authService.logout();
      }
    }
    else {
      request = request.clone({
        setHeaders: {
          Authorization: ""
        }
      });
    }
    return next.handle(request);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.