Angular2-jwt: tokenNotExpired() always return false

Created on 13 Apr 2017  Â·  31Comments  Â·  Source: auth0/angular2-jwt

Hi, I use your library without Ionic (native Angular 2) and all time tokenNotExpired() method return false.

When this code is exectued :

   loggedIn() {
    console.log(tokenNotExpired());
    return tokenNotExpired();
  }

  constructor(private router: Router) {}

  canActivate() {
    console.log(this.loggedIn());
    if(this.loggedIn()) {
      return true;
    } else {
      this.router.navigate(['login']);
      return false;
    }
  }

I use this code for angular routing canActivate: [AuthGuard].

But tokenNotExpired() always return false.

I don't understand why !

Most helpful comment

I think I found the solution, as I was fighting with a similar error:
The error is induced by Commit a6984d1df9315cc52b22b9c57b8badc4b6d1f47 (update token name).
With this commit, angular2-jwt assumes that the standard name of the token is _token_ , not any longer _access-token_.
The problem can be traced to the Quickstart of Auth0 for Angular 2 (https://auth0.com/docs/quickstart/spa/angular2/01-login), as it states (as of time of writing this):

// app/auth.service.ts

import { Injectable }      from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt';

// Avoid name not found warnings
declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('MyClientID', 'my.domain.dom', {});

  constructor() {
    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);
    });
  }

  public authenticated() {
    // Check if there's an unexpired JWT
    // This searches for an item in localStorage with key == 'id_token'
    return tokenNotExpired();
  }

}

So there are two possible fixes:
-Change in the constructor from localStorage.setItem('id_token', authResult.idToken)
to
localStorage.setItem('token', authResult.idToken)

-Use tokenNotExpired('id_token') instead of tokenNotExpired()

The third, impossible and stupid solution would be changing the default token name in JWT again.

All 31 comments

the token is valid, so isTokenExpired should return false. It's certainly confusing.

I update the post thx guy !

so return !isTokenExpired()

I think I found the solution, as I was fighting with a similar error:
The error is induced by Commit a6984d1df9315cc52b22b9c57b8badc4b6d1f47 (update token name).
With this commit, angular2-jwt assumes that the standard name of the token is _token_ , not any longer _access-token_.
The problem can be traced to the Quickstart of Auth0 for Angular 2 (https://auth0.com/docs/quickstart/spa/angular2/01-login), as it states (as of time of writing this):

// app/auth.service.ts

import { Injectable }      from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt';

// Avoid name not found warnings
declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('MyClientID', 'my.domain.dom', {});

  constructor() {
    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);
    });
  }

  public authenticated() {
    // Check if there's an unexpired JWT
    // This searches for an item in localStorage with key == 'id_token'
    return tokenNotExpired();
  }

}

So there are two possible fixes:
-Change in the constructor from localStorage.setItem('id_token', authResult.idToken)
to
localStorage.setItem('token', authResult.idToken)

-Use tokenNotExpired('id_token') instead of tokenNotExpired()

The third, impossible and stupid solution would be changing the default token name in JWT again.

Had the same issue. @qmsq's fix worked for me. Thank you.

A big thank you @qmsq!

The second solution looks better to me, since it's not very consistent to write localStorage.setItem('token', authResult.idToken) but this is a pure matter of preference.

Big up again, I was stuck on this for the last couple hours (grrr).

Yes, @qmsq's fix worked for me as well, thanks so much!

@qmsq made my day! Thank you!

same problem, the function is return from localStorage but is not using the factory options of tokenGetter

The implementation with google chrome debugger is:

function tokenNotExpired(tokenName, jwt) {
    if (tokenName === void 0) { tokenName = AuthConfigConsts.DEFAULT_TOKEN_NAME; }
    var token = jwt || localStorage.getItem(tokenName);// here is force to get from localStorage but not tokenGetter options of AuthConfig
    var jwtHelper = new JwtHelper();
    return token != null && !jwtHelper.isTokenExpired(token);
}

So another options is to pass the token in second parameters.

tokenNotExpired(null, sessionStorage.getItem("id_token"))

Thank...

Changing default token name was a tiny but breaking change in minor version update are unexpected. It happens... Looks like I need to constraint my lib versions to exact ones...

@qmsq
return tokenNotExpired('id_token'); saved my day! ty

@qmsq
thanks a lot man, you save my life.

I know this is closed, but can you update the README, as its confusing because the steps doesn't say that you now have to provide a parameter in return tokenNotExpired('id_token'). I'm following a tutorial using this and the guy didn't pass a parameter and it worked fine.

In case anyone is still a little confused I needed to do a little more detective work to understand the issue. Because I'm thinking wait isn't this supposed to be a self contained package?

The token used to be access-token and then it was changed to token

AuthConfigConsts.DEFAULT_TOKEN_NAME = 'token';

So I'm thinking how the #$ does changing it to id_token make it work? Why aren't we changing it to access-token.

I see in my auth.service.ts file it says id_token. So how did it ever work when the default token was access-token.

Turns out when looking at the history on April 11th the default token name was changed TWICE in one day. https://github.com/auth0/angular2-jwt/commits/a6984d1df9315cc52b22b9c57b8badc4b6d1f479/angular2-jwt.ts

id_token > access_token > token

So if like me you haven't touched your project since before April 11th then you'll change from id_token > token when you update the package.

I feel like tokenNotExpired('id_token') isn't the best solution, and changing the 'localstorage' property is better.

Alternative solution :

Modify your auth.service.ts file:

import { AuthConfigConsts } from 'angular2-jwt';

Search and replace all "id_token" to AuthConfigConsts.DEFAULT_TOKEN_NAME

@simeyla id_token and access_token are not the same, and they have changed it not so long ago. id_token is authentication (who you are) and access_token is authorization (it's sent as a Bearer token to the API). in the latest version the Auth0Lock by default returns only access_token, but not the id_token. I suppose you can change your auth.service.ts to check for access-token in authenticated() method or make Auth0Lock return id_token using options. What I did in auth.service.ts is:

var options = {
  auth: {
    params: {scope: 'openid email user_metadata app_metadata picture',
             responseType: 'id_token token'},
  }
}; 
....
lock = new Auth0Lock(myConfig.clientID, myConfig.domain, options);

and then:

this.lock.on('authenticated', (authResult) => {

      localStorage.setItem('token', authResult.idToken);
      localStorage.setItem('accessToken', authResult.accessToken);

hope it helps.

Thanks. So the double check in on April 11th was just a misunderstanding of
this distinction.
On Fri, May 19, 2017 at 21:15 Valerii Sosliuk notifications@github.com
wrote:

@simeyla https://github.com/simeyla id_token and access_token are not
the same, and they have changed it not so long ago. id_token is
authentication (who you are) and access_token is authorization (it's sent
as a Bearer token to API). in the latest version the Auth0Lock by default,
returns only access_token, and not the id_token. I suppose you can change
your auth.service.ts to check for access-token in authenticated method or
make Auth0Lock return id_token using options. What I in auth.service.ts is:

var options = {
auth: {
params: {scope: 'openid email user_metadata app_metadata picture',
responseType: 'id_token token'},
}
};
....
lock = new Auth0Lock(myConfig.clientID, myConfig.domain, options);

and then:

this.lock.on('authenticated', (authResult) => {

  localStorage.setItem('token', authResult.idToken);
  localStorage.setItem('accessToken', authResult.accessToken);

hope it helps.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/auth0/angular2-jwt/issues/334#issuecomment-302849402,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADfKVqhj-0FnfYA9tqoIEYFKPlgMA2j4ks5r7mj9gaJpZM4M8mdi
.

You can try
loggedIn() { if (localStorage.getItem('token')) return tokenNotExpired() }

we love you @qmsq

Thank you @qmsq !

Oh you saved my day ! Thx @qmsq

@qmsq thank you for the piece of mind after 2 hours of retracing steps to find out what I did wrong!!!

@qmsq thanks a lot dude, i use tokenNotExpired('id_token') and everything work very well.

@qmsq tnx man

Hi all of you,
I am afraid the solution proposed by @escardin is wrong. I will invite you to read the official docs of angular2-jwt, https://github.com/auth0/angular2-jwt#checking-authentication-to-hideshow-elements-and-handle-routing.

It happen to me the same but I realize my token was expired, so I was getting the correct response from tokenNoInspired(). Also I want to point out that tokenNoInspired function will by default assume the token name is token unless a token name is passed to it. Ex: tokenNotExpired(null, 'user_token')

You can find the token's expiration date with,
import {JwtHelper} from 'angular2-jwt';

jwtHelper: JwtHelper = new JwtHelper();
this.jwtHelper.getTokenExpirationDate(token)

I was using tokenNotExpired and it was always returning false, but instead I used JwtHelper.isTokenExpired and not it is working.

Solution :
Please use token instead of id_token.

For ex:

localStorage.setItem('token', token);
const token = localStorage.getItem('token');

and use return tokenNotExpired(); for returning purpose.

Following is the working code snippet:
``` import { Injectable } from '@angular/core';
import {Http, Headers} from '@angular/http';
import 'rxjs/add/operator/map';
import {tokenNotExpired} from 'angular2-jwt';

@Injectable()
export class AuthService {
authToken: any;
user: any;

constructor(private http: Http) { }

registerUser(user) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:3000/users/register', user, {headers: headers})
.map(res => res.json());
}

authenticateUser(user) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:3000/users/authenticate', user, {headers: headers})
.map(res => res.json());
}

getProfile() {
const headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.get('http://localhost:3000/users/profile', {headers: headers})
.map(res => res.json());
}

// Storing user id and token in local memory
storeUserData(token, user) {
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}

loadToken() {
const token = localStorage.getItem('token');
this.authToken = token;
}

loggedIn() {
return tokenNotExpired();
}

logout() {
this.authToken = null;
this.user = null;
localStorage.clear();
}

}
```

Thanks, @rhtpandeyIN its works

@qmsq you saved my soul today. God bless you sir

i have face the same problem that tokenNotExpired() is always returning false.
this solution fixed the error

in the auth.service.ts

change:
`loggedIn() {

return tokenNotExpired();

}`

to:
`loggedIn() {

return tokenNotExpired('tokenid');

}`

'tokenid' refers to the var name for the token in the local storage

Thanks a whole lot

On Sun, Jun 24, 2018 at 11:51 PM, Sanju maheeshan notifications@github.com
wrote:

i have face the same problem that tokenNotExpired() is always returning
false.
this solution fixed the error

in the auth.service.ts

change:
`loggedIn() {

return tokenNotExpired();

}`

to:
`loggedIn() {

return tokenNotExpired('tokenid');

}`

'tokenid' refers to the var name for the token in the local storage

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/auth0/angular2-jwt/issues/334#issuecomment-399850040,
or mute the thread
https://github.com/notifications/unsubscribe-auth/Ak7Hi9wwWQaYqKe7v32fevdOL4w3EcMCks5uAIiJgaJpZM4M8mdi
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

huineng picture huineng  Â·  4Comments

jaumard picture jaumard  Â·  5Comments

JaxonWright picture JaxonWright  Â·  4Comments

kolkov picture kolkov  Â·  3Comments

n0490b picture n0490b  Â·  4Comments