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

sessionDataUpdated trigger on internal session passes a blank content object after authenticating with the Torii provider, causing session to clear itself #921

Closed
shicholas opened this issue Mar 5, 2016 · 16 comments
Labels

Comments

@shicholas
Copy link

Hello,

After successfully authenticating with the Torii Authenticator, I am briefly logged in before Ember clears my session and sends the invalidationSucceededmessage (which I checked by intercepting it in my application route.

When I delete these two lines: https://github.com/simplabs/ember-simple-auth/blame/master/addon/internal-session.js#L14-L15, everything is fine. Do you know what perchance is causing the re-initialization of my internal-session?

Any advice would be greatly appreciated. Thank you,

@shicholas
Copy link
Author

update, it's just line 14 that needs to go. I made a (probably wrong PR) to talk about it. If there is extra context that can help please let me know.

@shicholas
Copy link
Author

sorry for the spam, after poking around some more it looks like the sessionDataUpdated trigger is being sent which is causing the issue, trying to debug more around this, and why it would clear out my session.

@shicholas shicholas changed the title Internal Session re-inits causing session to be destroyed Session Data Updated passes a blank content object, causing session to re-initialize Mar 5, 2016
@shicholas shicholas changed the title Session Data Updated passes a blank content object, causing session to re-initialize sessionDataUpdated trigger on internal session passes a blank content object after authenticating with the Torii provider, causing session to clear itself Mar 5, 2016
@shicholas
Copy link
Author

I must have a gross misunderstanding, I thought the data I get from Torii, https://github.com/simplabs/ember-simple-auth/blob/master/addon/authenticators/torii.js#L89, gets passed here, https://github.com/simplabs/ember-simple-auth/blob/master/addon/internal-session.js#L161. But instead that value is the initialized value of {authenticated: {} }.

How can I pass the appropriate data?

@marcoow
Copy link
Member

marcoow commented Mar 6, 2016

Can you share your code please? I'm not really sure what you're doing.

@shicholas
Copy link
Author

The following are my custom authenticator, authorizer and torii provider (I know it's third party, but I think I'm doing it right). When I log in (by calling authenticate on my authenticator) I see my session logged in very briefly by looking at the local storage for authenticated. Immediately after logging in, the session trigger, sessionDataUpload executes with { content: { authenticated: {} } } causing my session to clear itself out.

app/authenticators/api.js

import Ember from 'ember';
import ToriiAuthenticator from 'ember-simple-auth/authenticators/torii';

export default ToriiAuthenticator.extend({
  torii: Ember.inject.service(),
  authenticate(provider, options) {
    this._assertToriiIsPresent();

    return this.get('torii').open(provider, options || {}).then((data) => {
      this._authenticateWithProvider(provider, data);


      // this code helps, but the ``sessionDataUpdated`` trigger 
      // happens many times, and I see my session oscillate 
      // between being logged in and out. I believing fixing the issue 
      // above would solve this too.
      this.trigger('sessionDataUpdated', data);

      return data;
    });
  }
});

app/authorizers/api.js

import Ember from 'ember';
import BaseAuthorizer from 'ember-simple-auth/authorizers/base';

const { isEmpty } = Ember;

export default BaseAuthorizer.extend({
  authorize(sessionData, block) {
    let accessToken = sessionData.access_token;

    if (!isEmpty(accessToken)) {
      block('Authorization', `Bearer ${accessToken}`);
    }
  }
});

app/torii-providers/api.js

import OAuth2 from 'torii/providers/oauth2-code';
import {configurable} from 'torii/configuration';

export default OAuth2.extend({
  name: 'api',
  init() {
    this.set('clientID', this.get('apiKey'));
  },

  baseUrl: configurable('baseUrl'),

  redirectUri: configurable('redirectUri'),
  responseParams: ['access_token', 'user_id', 'first_name'],

  requiredUrlParams: ['client_id', 'redirect_uri', 'response_type'],

  open() {
    let name        = this.get('name');
    let url         = this.buildUrl();
    let redirectUri = this.get('redirectUri');
    let responseParams = this.get('responseParams');

    return this.get('popup').open(url, responseParams).then((authData) => {
      return {
        access_token: authData.access_token,
        first_name: authData.first_name,
        user_id: authData.user_id,
        provider: name,
        redirectUri
      };
    });
  },

  fetch(data) {
    return data;
  }
});

I hope I explained this well enough, let me know how I can clarify.

@marcoow
Copy link
Member

marcoow commented Mar 7, 2016

When I log in (by calling authenticate on my authenticator)

Can you share the code you use to authenticate the session as well? Looks like you're not using the session service's API to authenticate the session?

@shicholas
Copy link
Author

By that do you mean invoke the authentication from a session? I have this action in my application route:

app/routes/application.js

import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';

export default Ember.Route.extend(ApplicationRouteMixin, {
  session: Ember.inject.service('session'),
  actions: {
    authenticate() {
      this.get('session')
        .authenticate('authenticator:api', 'api')
        .catch((reason) => {
          console.log(reason);
        });
    },
    logout() {
      this.get('session').invalidate();
    }
  }
});

@marcoow
Copy link
Member

marcoow commented Mar 7, 2016

That seems correct actually. You can change you authenticator to just

import Ember from 'ember';
import ToriiAuthenticator from 'ember-simple-auth/authenticators/torii';

export default ToriiAuthenticator.extend({
  torii: Ember.inject.service()
});

though. You should never trigger sessionDataUpdated manually like that, especially not before the session is authenticated as above.

Also make sure your torii provider returns a promise - looks like it just returns the data directly in your case.

@shicholas
Copy link
Author

I have tried a few different promise alternatives like you suggested, but can't seem to figure this out. e.g. in my torii provider:

import OAuth2 from 'torii/providers/oauth2-code';
import {configurable} from 'torii/configuration';

export default OAuth2.extend({
  name: 'api',
  init() {
    this.set('clientID', this.get('apiKey'));
  },

  baseUrl: configurable('baseUrl'),

  redirectUri: configurable('redirectUri'),
  responseParams: ['access_token', 'user_id', 'first_name'],

  requiredUrlParams: ['client_id', 'redirect_uri', 'response_type'],

  open() {
    let name           = this.get('name');
    let url            = this.buildUrl();
    let redirectUri    = this.get('redirectUri');
    let responseParams = this.get('responseParams');

    return new Ember.RSVP.Promise((resolve, reject) => {
      this.get('popup').open(url, responseParams).then((authData) => {
        resolve({
          access_token: authData.access_token,
          first_name: authData.first_name,
          user_id: authData.user_id,
          provider: name,
          redirectUri
        });
      }).catch((error) => {
        reject(error);
      });
    });
  },

  fetch(data) {
    return data;
  }
});

I still see my session logged in, then immediately after I see it log out. Is there anything else that you can think of that could invalidate the session?

@marcoow
Copy link
Member

marcoow commented Mar 16, 2016

@rmachielse: this is actually a problem with the async session stores as well - I just had a pairing session with @shicholas and was able to verify that. While the session is still being authenticated the session store seems to already fire a sessionDataUpdated event (with the old, pre-authentication session data) which leads to the session being invalidated right away.

At this point I'm thinking we might have to revert the async session store feature. Would be great if you could do some debugging/investigation - maybe there's an easy way to fix it.

@rmachielse
Copy link
Contributor

@marcoow hmm, maybe the issues are related. I'll see if I can reproduce this as well and look into it.

@marcoow
Copy link
Member

marcoow commented Mar 16, 2016

@rmachielse: thanks!

@rmachielse
Copy link
Contributor

@shicholas can you verify wether the possible fix on #927 fixes your problem too?

@shicholas
Copy link
Author

@rmachielse it works! I tried the code on #931 on your fork and everything seemed to work fine. thanks so much!

@rmachielse
Copy link
Contributor

@shicholas glad it works!

@shicholas
Copy link
Author

thanks for closing, fwiw I've had no issues whatsoever with 1.1.0. thanks for everything!

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

No branches or pull requests

3 participants