简体   繁体   English

Jwt令牌在角度6中到期

[英]Jwt token expiration in angular 6

I am making an angular app that uses jwt to authenticate db calls.However the issue 我正在制作一个角度应用程序,使用jwt来验证db调用。但是问题
is that when the token expires at the server,the app starts giving blank pages instead of data as the expired token is still in the local storage.After some research I found out that jwt2 library can be used to track token expiry.However even after using that I have to refresh the page to redirect to the login page.I am still able to move within the components. 当令牌在服务器到期时,应用程序开始提供空白页面而不是数据,因为过期的令牌仍在本地存储中。经过一些研究,我发现jwt2库可用于跟踪令牌到期。但是甚至之后使用它我必须刷新页面以重定向到登录页面。我仍然能够在组件内移动。 I want that as soon as the token is expired the login page comes or the token is refreshed and even when moving between components,if the token is expired the user should be redirected to login page or the token should be refreshed.I don't know what else I need to do.Please help.Thanks in advance. 我希望一旦令牌过期,登录页面就会出现或令牌被刷新,即使在组件之间移动,如果令牌过期,用户也应该被重定向到登录页面或者令牌应该刷新。我不会知道我还需要做什么。请帮助。谢谢。

Here is my auth guard: 这是我的认证:

Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(private router: Router,private authService:AuthService ){ }

  canActivate(

    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    if (!(this.authService.isTokenExpired()) ){
      // logged in so return true
      console.log("Logged IN");
      return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
    return true;
  }
}

Here is my auth Service: 这是我的身份验证服务:

 const helper = new JwtHelperService();

    @Injectable({
      providedIn: 'root'
    })
    export class AuthService {

      constructor(private http: HttpClient) { }

    /*  public login<T>(username: string, password: string): Observable<HttpResponse<T>> {
        let headers = new HttpHeaders();
 const clientId = 'rosClient';
    const secret = 'secret';
        headers = headers.append("Authorization", "Basic " + btoa(`${username}:${password}`));
        headers = headers.append("Content-Type", "application/x-www-form-urlencoded");
        return this.http.get<T>('/auth/login', {
          headers: headers,
          observe: 'response'
        });
      }*/


      public login<T>(username: string, password: string): Observable<HttpResponse<T>> {
        let headers = new HttpHeaders();
        const clientId = 'clientid';
        const secret = 'secret';
        headers = headers.append('Authorization', 'Basic ' + btoa(`${clientId}:${secret}`));
        headers = headers.append('Content-Type', 'application/x-www-form-urlencoded');
        const params = new HttpParams().set('username', username).set('password', password).set('grant_type', 'password').set('scope', 'read');
        return this.http.post<T>('/oauth/token', params.toString(), {
          headers,
          observe: 'response'
        });
      }

      public logout<T>() {
        this.http.post('/oauth/revoke_token', '', {}).subscribe();
      }

      getToken(): string {
        return localStorage.getItem(TOKEN_NAME);
      }



      isTokenExpired(token?: string): boolean {
        if(!token) token = this.getToken();
        if(!token) return true;

        const date = helper.getTokenExpirationDate(token);
        console.log(date);
        if(date === undefined) return false;
        return !(date.valueOf() > new Date().valueOf());
      }
    }

Below is my error interceptor: 下面是我的错误拦截器:

@Injectable()
export class H401Interceptor implements HttpInterceptor {

    constructor(private authService: AuthService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                // this.authService.logout();
                // location.reload(true);
                localStorage.removeItem('currentUser');
            }

            const error = err.error.message || err.statusText;
            return throwError(error);
        }));
    }
}

You can use HttpInterceptor, when the backend answers with '401 Unauthorized', you delete the token and navigate to the sign in page. 您可以使用HttpInterceptor,当后端以“401 Unauthorized”回答时,您删除令牌并导航到登录页面。 Here's a working code: 这是一个有效的代码:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      setHeaders: {
        Authorization: `Bearer ${this.storageService.retrieve(tokenKey)}`,
        'Content-Type': 'application/json'
      }
    });
    return next.handle(request).pipe(
      catchError(
        (err, caught) => {
          if (err.status === 401){
            this.handleAuthError();
            return of(err);
          }
          throw err;
        }
      )
    );
  }
  private handleAuthError() {
    this.storageService.delete(tokenKey);
    this.router.navigateByUrl('signIn');
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM