Search code examples
ember.jsjwtember-simple-auth

Session properties and JWT claims can't be accessed with embre-simple-auth-token


I have a basic working authentication system in my Ember app. I can receive a JWT and my app will log me in. The problem is that I can't access anything with something like this.get('session').get('data.id') as shown in an example on ember-simple-auth's GitHub page.

Here's the response from my authentication request:

{token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFiY…yMyJ9.X0O3xMVikn-5l9gXBU5a2XF6vlMmTzm4mCqUNA68e-A", test: "abc123"}

Here's the payload of the token:

{
  "id": "abc123"
}

Yet, calling this.get('session').get('data.id') doesn't return anything. I also tried other things like this.get('session').get('id').

this.get('session').get('data') returns:

{"authenticated":{"authenticator":"authenticator:jwt","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFiYzEyMyJ9.X0O3xMVikn-5l9gXBU5a2XF6vlMmTzm4mCqUNA68e-A","test":"abc123"}}

So there is technically a way to read test but it doesn't seem like the right way.

this.get('session') exists, but is empty. Setting properties work well and they can be accessed afterwards.

How do I access the claims? ember-simple-auth-token has a specific authenticator for JWT so I assume it should be able to read the token.


Solution

  • You can get the decoded payload like this:

    JSON.parse(atob(this.get('session.data.authenticated.token').split('.')[1]))
    

    Which is talked about in this issue.

    UPDATE

    Just looked at this again and realised that I might have misunderstood you. The method I mentioned above is how to decode the claims from the token, however that's not how you would access the claims from templates/routes etc.

    Here is a good blog post that shows how to make the claims more easily accessible.

    Basically whenever a user is authenticated, a property is added to the session which allows the claims to be accessed like this.get('session.claims.id').

    In the blog post a user is fetched from the api and saved as session.account. If you would rather just set the claims directly from the token to the session you can do this:

    services/session-account.js

    import Ember from 'ember';
    const { inject: { service }, RSVP } = Ember;
    export default Ember.Service.extend({
      session: service('session'),
      store: service(),
      loadCurrentUser() {
        const token = this.get('session.data.authenticated.token');
        if (!Ember.isEmpty(token)) {
          var claims = JSON.parse(atob(token.split('.')[1]));
          this.set('session.claims', claims);
        }
      }
    });
    

    Hopefully that's more what you were looking for.