15

I need help in handling expired token in my angular application. My api has the expired time but my problem is when i forgot to log out of my angular application, after some time, i still can access the homepage but without data. Is there something i can do about this? Are there libraries that can handle this? or are there something i could install? Better, if i nothing will be installed. Here's my authentication code below? Can i add anything that can handle expiration and I won't be able to access the homepage if it expires.

auth.service.ts

 export class AuthService {
  private loggedIn = false;

  constructor(private httpClient: HttpClient) {
  }

  signinUser(email: string, password: string) {  
    const headers = new HttpHeaders() 
    .set('Content-Type', 'application/json');

    return this.httpClient
    .post(
      'http://sample.com/login', 
       JSON.stringify({ email, password }), 
       { headers: headers }
    )
    .map(
        (response: any) => {
          localStorage.setItem('auth_token', response.token);
          this.loggedIn = true;
          return response;
        });
   }

    isLoggedIn() {
      if (localStorage.getItem('auth_token')) {
        return this.loggedIn = true;
      }
    }

   logout() {
     localStorage.removeItem('auth_token');
     this.loggedIn = false;
    }
}

authguard.ts

@Injectable()
export class AuthGuard implements CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

    if (this.authService.isLoggedIn()) {
      // logged in so return true
      return true;
    }

    else {
      // not logged in so redirect to login page with the return url
      this.router.navigate(['signin'])
      return false;
      }
  }
}
Joseph
  • 7,042
  • 23
  • 83
  • 181
  • You can force app to clear login status when leaving the app. – Pengyy Sep 11 '17 at 02:11
  • 1
    @Pengyy. But i think that's not how professional web app works, right? They still can access their account after they close the browser. – Joseph Sep 11 '17 at 02:15
  • This is depend on your app's authentication strategy. For me, it's strange that app can be still logged in but API is not reachable any more. – Pengyy Sep 11 '17 at 02:21
  • what is happening on logout? – angularrocks.com Sep 11 '17 at 02:34
  • @Kuncevic. Do you mean when i click the logout button? It logouts the app and i won't be able to access the homepage – Joseph Sep 11 '17 at 02:35
  • @Kuncevic. This is how my app works. When i forgot to logout and i open the browser again, i still can access the homepage and have data in it. After some time, the token expires but my problem is i'm still on my homepage but have no data in it, i should be redirected to the login page – Joseph Sep 11 '17 at 02:41

2 Answers2

9

You can do this using http interceptors.

intercept(req: HttpRequest<any>, next: HttpHandler) {
  if(!localStorage.getItem('token'))
    return next.handle(req);

  // set headers
  req = req.clone({
    setHeaders: {
      'token': localStorage.getItem('token')
    }
  })

  return next.handle(req).do((event: HttpEvent<any>) => {
    if(event instanceof HttpResponse){
      // if the token is valid
    }
  }, (err: any) => {
    // if the token has expired.
    if(err instanceof HttpErrorResponse){
      if(err.status === 401){
        // this is where you can do anything like navigating
        this.router.navigateByUrl('/login');
      }
    }
  });
}

Here's the full solution

Amirhosein Al
  • 470
  • 6
  • 18
8

I think there is two solution you can play with.

The first one you can just call you logout function when browser getting closed like:

  @HostListener('window:unload', ['$event'])
  handleUnload(event) {
    this.auth.logout();
  }

https://developer.mozilla.org/de/docs/Web/Events/unload

OR

 @HostListener('window:beforeunload', ['$event'])
      public handleBeforeUnload(event) {
        this.auth.logout();
      }

https://developer.mozilla.org/de/docs/Web/Events/beforeunload

This way alway when browser getting closed your this.auth.logout(); will be called automatically.

Second you can install library like angular2-jwt it can help you to detect if token has expired

jwtHelper: JwtHelper = new JwtHelper();

useJwtHelper() {
  var token = localStorage.getItem('token');

  console.log(
    this.jwtHelper.decodeToken(token),
    this.jwtHelper.getTokenExpirationDate(token),
    this.jwtHelper.isTokenExpired(token)
  );
}
angularrocks.com
  • 26,767
  • 13
  • 87
  • 104
  • What do you recommend, if i close browser, i will call logout? OR When i forgot to logout and i open the browser again, i still can access the homepage and have data in it. After some time, the token expires but my problem is i'm still on my homepage but have no data in it, i should be redirected to the login page – Joseph Sep 11 '17 at 02:49
  • I think you better use the library like `angular2-jwt` this way you can handle your case in proper way it has all functionality you need. – angularrocks.com Sep 11 '17 at 02:54
  • @Kuncevice. Does it support angular 4? I have an error installing it – Joseph Sep 11 '17 at 03:02
  • @Joseph Yes it is supports `angular 4` I just installed that in the app and no issues. Make sure you are installing `angular2-jwt` not `angular-jwt` – angularrocks.com Sep 11 '17 at 03:53
  • what exactly you are having problem with? – angularrocks.com Sep 11 '17 at 03:56
  • I just want to implement angular2-jwt in my code. If it is ok with you that you can write code on my code :) – Joseph Sep 11 '17 at 04:01
  • I think you have to check that tutorial first http://jasonwatmore.com/post/2016/08/16/angular-2-jwt-authentication-example-tutorial and check the docs https://github.com/auth0/angular2-jwt, then if you have any issues just create another question – angularrocks.com Sep 11 '17 at 04:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154097/discussion-between-kuncevic-and-joseph). – angularrocks.com Sep 11 '17 at 04:05
  • Is there another solution to this problem except the above solutions? – Amirhosein Al Jun 13 '18 at 14:44