Angular2-jwt: TypeError: Cannot read property 'split' of undefined (crashes site on logout)

Created on 28 Jul 2018  ·  6Comments  ·  Source: auth0/angular2-jwt

Hi guys, this issue only occurs when the user is logged out and completely crashes the app. I get a bunch of errors about not being able to read 'split' of undefined.

AppComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'split' of undefined
    at JwtHelperService.push../node_modules/@auth0/angular-jwt/src/jwthelper.service.js.JwtHelperService.decodeToken (jwthelper.service.js:70)
    at JwtHelperService.push../node_modules/@auth0/angular-jwt/src/jwthelper.service.js.JwtHelperService.getTokenExpirationDate (jwthelper.service.js:83)
    at JwtHelperService.push../node_modules/@auth0/angular-jwt/src/jwthelper.service.js.JwtHelperService.isTokenExpired (jwthelper.service.js:96)
    at AuthService.push../src/app/core/auth/auth.service.ts.AuthService.isLoggedIn (auth.service.ts:124)

As I said, this only happens when the user logs out but completely crashed the app so they can't log back in.

Here's how JWT is implemented, it's been this way for a few months and nothing's changed so I have no idea what is going on here.

app.module.ts

export function tokenGetter() {
  const user = JSON.parse(localStorage.getItem('user'));
  const userToken = user ? user.token : null;
  return userToken;
}

...

JwtModule.forRoot({
  config: {
    tokenGetter: tokenGetter,
    whitelistedDomains: ['localhost:4200']
  }
}),

auth.service.ts

import { JwtHelperService } from '@auth0/angular-jwt';

constructor(
    private http: HttpClient,
    private jwtHelper: JwtHelperService
  ) {}

...

isLoggedIn() {
  return this.jwtHelper.isTokenExpired() ? false : true;
}

The only way I can get back into the app to log back in is to comment out the return statement within the isLoggedIn function.

Any help would be very much appreciated, thanks.

Most helpful comment

Thanks @d-go, that is much cleaner. I look forward to when isTokenExpired returns false for null tokens 🙂

All 6 comments

Ok so looking through some other issues and pull requests, it seems that isTokenExpired() doesn't handle null (expired) tokens... if I'm right in that assumption then isn't this method completely broken? By it's name it should return false if the token is null and/or expired. It's also not mentioned in the readme anywhere so I assume this is in fact a bug.

495 seems like it should have fixed this from the description, but for now and for anyone else seeing this issue this is how I fixed it:

isLoggedIn() {
    const token = this.user ? (this.user.token ? this.user.token : null) : null;
    return token ? (this.jwtHelper.isTokenExpired() ? false : true) : false;
  }

Well... it seems that actually the isTokenExpired() method doesn't handle null tokens, however, I think you can simplify your solution:

isLoggedIn() {
    const token = this.jwtHelper.tokenGetter();
    if (!token) return false;

    return !this.jwtHelper.isTokenExpired();
}

But I agree that if the token is null, the method should treat the token as expired

Thanks @d-go, that is much cleaner. I look forward to when isTokenExpired returns false for null tokens 🙂

Same problem but a bit different code. Angular 7.0.

import { JwtHelperService } from '@auth0/angular-jwt';

I dropped your code into the service that returns a JWT from AWS Cognito with AWS Amplify, the AWS JavaScript SDK for Cognito. I can see the JWT in localStorage and I believe that it is Oauth.

let myRawToken;
const decodedToken = this.helper.decodeToken(myRawToken);
console.log('decodedToken: ', decodedToken);

[TypeError: Cannot read property 'split' of undefined
at JwtHelperService.push../node_modules/@auth0/angular-jwt/src/jwthelper.service.js.JwtHelperService.decodeToken (vendor.js:141139)
at amplifyService.auth.currentAuthenticatedUser.then.user (main.js:585)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (polyfills.js:2733)
at Object.onInvoke (vendor.js:73412)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (polyfills.js:2732)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (polyfills.js:2483)
at polyfills.js:3217
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:2766)
at Object.onInvokeTask (vendor.js:73403)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:2765)](url)

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇‍♂️

My issue is resolved. I dug through the code of isTokenExpired and noticed that it expected an encoded token. I was passing in a decoded token by mistake.

Was this page helpful?
0 / 5 - 0 ratings