0

I have model called posts. And component called posts-list

app/templates/components/posts-list.hbs:

{{#each posts as |post|}}
  {{post.title}}
{{/each}}

main template:

{{posts-list posts=model}}

app/routes/posts.js:

export default Ember.Route.extend({
  model() {
    return this.store.findAll('post');
  }
});

Issue description: Those posts can be loaded if user authorised or not, but when user authorised titles will be a bit different (data comes from server using JWT).

I'm using ember-simple-auth with custom authorizer and authenticator. Auth process looks like - user clicks link and going to backend, then it redirects back to main page with token as GET param. I overrided setupController in app/routes/application.js and calling

this.get('session').authenticate('authenticator:custom', token);

In authenticator i have function:

  authenticate: function(token) {
    return new Ember.RSVP.Promise((resolve, reject) => {
      Ember.$.ajax({
        url: ENV.APP.API_HOST + '/api/users',
        type: 'GET',
        contentType: 'application/json',
        dataType: 'json',
        headers: {
          'Accept': 'application/json',
          'Authorization': token
        }
      }).then(function(response) {
        Ember.run(function() {
          resolve({ token: token });
        });
      }, function(xhr, status, error) {
        var response = xhr.responseText;
        Ember.run(function() {
          reject(response);
        });
      });
    });
  }

So i'm trying to get current user using token and if it success, then user is authorized.

Everything works fine except one thing. Posts is requested before requesting current user, so even if user actually authorized he will see non authorized content. Is it possible to tell Ember about loading order (or reload data after auth, but this will produce second request which is not preferred).

sl_bug
  • 5,066
  • 5
  • 21
  • 22

1 Answers1

0

The beforeModel was introduced for this purpose.

beforeModel(transition) {
  let token = transition.queryParams.token;
  let promise = this.get('session').authenticate('authenticator:custom', token);

  promise.then(()=> {
    alert("You're in!");
  });

  promise.catch(()=> {
    transition.abort();
    this.transitionTo('loggin');
  });
}
kiwiupover
  • 1,782
  • 12
  • 26
  • But how I can access queryParams inside beforeModel to trigger authenticate? – sl_bug Feb 15 '16 at 19:13
  • The `queryParams` are a part of the transition object, `transition.queryParams` I will update the answer in a minute – kiwiupover Feb 15 '16 at 20:28
  • It works when token param is set for each request, but in my case token param set only after auth and then it's cleared. I've added if (this.get('session.isAuthenticated')) { return; } in beforeModel, but it does not help. Also unauthenticated user should be able to view this page too, but he will receive a bit different content from backend – sl_bug Feb 15 '16 at 20:54
  • And also anyway for authenticated user posts request sent before requesting /users, so he receives content for unauthenticated user – sl_bug Feb 15 '16 at 20:56
  • Managed to fix it using `if (!Ember.isEmpty(token) && !this.get('session.isAuthenticated')) { return promise }` But since ember-simple-auth tries to transition to '/' after auth it fails with error (found issue in ember - https://github.com/emberjs/ember.js/issues/12169) – sl_bug Feb 16 '16 at 05:06