Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tokenNotExpired() always return false #334

Closed
axelpcr opened this issue Apr 13, 2017 · 31 comments
Closed

tokenNotExpired() always return false #334

axelpcr opened this issue Apr 13, 2017 · 31 comments

Comments

@axelpcr
Copy link

axelpcr commented Apr 13, 2017

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 !

@escardin
Copy link
Contributor

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

@axelpcr
Copy link
Author

axelpcr commented Apr 13, 2017

I update the post thx guy !

@escardin
Copy link
Contributor

so return !isTokenExpired()

@qmsq
Copy link

qmsq commented Apr 13, 2017

I think I found the solution, as I was fighting with a similar error:
The error is induced by Commit a6984d1 (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.

@shteeven
Copy link

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

@ghost
Copy link

ghost commented Apr 13, 2017

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).

@alligatorio
Copy link

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

@mp-loki
Copy link

mp-loki commented Apr 17, 2017

@qmsq made my day! Thank you!

@zahasoftware
Copy link

zahasoftware commented Apr 23, 2017

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...

@ozelen
Copy link

ozelen commented Apr 25, 2017

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...

@axhcypod
Copy link

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

@chusri
Copy link

chusri commented Apr 27, 2017

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

@estradamarkie
Copy link

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.

@simeyla
Copy link

simeyla commented May 20, 2017

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.

@simeyla
Copy link

simeyla commented May 20, 2017

Alternative solution :

Modify your auth.service.ts file:

import { AuthConfigConsts } from 'angular2-jwt';

Search and replace all "id_token" to AuthConfigConsts.DEFAULT_TOKEN_NAME

@mp-loki
Copy link

mp-loki commented May 20, 2017

@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.

@simeyla
Copy link

simeyla commented May 20, 2017 via email

@ortin-dev
Copy link

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

@hussainwali74
Copy link

we love you @qmsq

@enavu
Copy link

enavu commented Aug 1, 2017

Thank you @qmsq !

@ktounet
Copy link

ktounet commented Aug 23, 2017

Oh you saved my day ! Thx @qmsq

@joe-mw
Copy link

joe-mw commented Aug 25, 2017

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

@ghost
Copy link

ghost commented Aug 29, 2017

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

@nitheeshmashraf
Copy link

@qmsq tnx man

@luillyfe
Copy link

luillyfe commented Nov 10, 2017

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)

@milianoo
Copy link

milianoo commented Mar 5, 2018

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

@rhtpandeyIN
Copy link

rhtpandeyIN commented Mar 21, 2018

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 {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();
  }

}

@keshav4u
Copy link

Thanks, @rhtpandeyIN its works

@chenkie chenkie closed this as completed May 14, 2018
@mpakoivo
Copy link

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

@maheeshan
Copy link

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

@mpakoivo
Copy link

mpakoivo commented Jun 26, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests