ember simple auth session, ember data, and passing a Authorization header

1.6k Views Asked by At

I have a working oauth2 authentication process where I get an access token (eg from facebook) using ember simple auth, send it to the back end which calls fb.me() and then uses JWT to create a token. This token is then sent back to the ember app, which then has to send it with every server request, include those requests made by ember-data.

I also need to have this token available after a browser reload.

I have tried many options, where I set a property 'authToken' on the session - I believe that this uses local storage to persist the authenticated session.

But I always seem to have trouble with coordinating the retrieval of this token - either I don't have access to the session, or the token is no longer on the session, or I can't change the ember data headers.

Does anyone have a working simple example of how this can be done - I think it should be easy, but I'm obviously missing something!

Thanks.

Update

The only thing I've been able to get working is to use torii as shown below, but the session content is still lost on refresh - I can see its still authenticated, but its lost the token I set here. So I'm still looking for a real solution.

   authenticateWithGooglePlus: function () {
      var self = this;
      this.get('session').authenticate('simple-auth-authenticator:torii', 'google-oauth2')
        .then(function () {
          resolveCodeToToken(self.get('session'), self);
        });
    }

resolveCodeToToken gets the bearer token from the server, sets it on the session and then transitions to the protected page:

function resolveCodeToToken(session, route) {
  var authCode = session.content.authorizationCode;
  var type = session.content.provider.split('-')[0];
  $.ajax({
    url: 'http://localhost:4200/api/1/user/auth/' + type,
    data: {authCode: authCode}
  }).done(function (response) {
    // todo handle invalid cases - where user is denied access eg user is disabled
    session.set('authToken', response.token);
    route.transitionTo('activity', moment().format('DDMMYYYY'));
  });
}

And I have a custom authorizer for putting the token (stored in the session) on every request:

import Base from 'simple-auth/authorizers/base';

export default Base.extend({
  authorize: function(jqXHR, requestOptions) {
    var accessToken = this.get('session.content.authToken');
     if (this.get('session.isAuthenticated') && !Ember.isEmpty(accessToken)) {
       jqXHR.setRequestHeader('Authorization', accessToken);
     }
  }
});

I'm not sure why this.get('session.content.authToken') would be undefined after a refresh, I thought by default the session was persisted in local storage. The fact that it is authenticated is persisted, but thats useless without the token since the server will reject calls to protected endpoints.

1

There are 1 best solutions below

13
On

You'd want to implement your own custom authenticator that first gets a token from Facebook and then sends that to your own server to exchange it for a token for your app. Once you have that you get authorization of ember-data requests as well as session persistence etc. for free.

Have a look at this example: https://github.com/simplabs/ember-simple-auth/blob/master/examples/7-multiple-external-providers.html