Обновление Ember-data 1.0.0.beta.9 изменяет порядок загрузки данных сеанса простой аутентификации

В ember-data 1.0.0-beta.8 ember-simple-auth загружает текущего пользователя из моего API перед выполнением любых других запросов. Это гарантирует, что текущие пользовательские данные будут доступны на других маршрутах. После обновления до ember-data 1.0.0-beta.9 текущий пользователь загружается после выполнения других запросов API.

Есть ли способ заставить ember-simple-auth загрузить текущего пользователя перед другими данными, используя ember-data 1.0.0-beta.9?

Мой пользовательский простой сеанс аутентификации выглядит следующим образом:

import SimpleAuthSession from 'simple-auth/session';

export default SimpleAuthSession.extend({
  updateCurrentUser: function() {
    var self = this;
    var userId = this.get('user_id');
    if (!Ember.isEmpty(userId)) {
      self.set('currentUser', self.container.lookup('store:main').find('current-user', userId));
    }
  }.observes('user_id')
});

Мой инициализатор аутентификации:

import MyAppSession from 'my-app-ember/lib/my-app-session';
import FacebookAuthenticator from 'my-app-ember/lib/facebook-authenticator';

export default {
  name: 'authentication',
  before: 'simple-auth',

  initialize: function(container) {
    container.register('session:my-app-session', MyAppSession);
    container.register('simple-auth-authenticator:facebook', FacebookAuthenticator);

    window.ENV = window.ENV || {};

    window.ENV['simple-auth'] = {
      session: 'session:my-app-session',
      authorizer: 'simple-auth-authorizer:oauth2-bearer',
      routeAfterAuthentication: 'moments'
    };

    window.ENV['simple-auth-oauth2'] = {
      serverTokenEndpoint: MyAppEmberENV.API_NAMESPACE + '/oauth/token'
    };
  }
};

Вот пример места, где я зависел от объекта currentUser, который должен быть установлен в сеансе в хуке afterModel, и после обновления он не работает:

export default Ember.Route.extend({
  model: function() {
    return this.store.find('moment');
  },

  afterModel: function() {
    if (!this.get('session.currentUser.isReturningUser')) {
      this.transitionTo('settings');
    }
  }
});

person Peter Brown    schedule 21.08.2014    source источник
comment
Я не уверен, вижу ли я, как это работало бы в ember data 1.0 beta 8.   -  person Kingpin2k    schedule 21.08.2014
comment
@Kingpin2k Это работает, но я буду открыт для предложений, как сделать его лучше. Что не похоже на то, что это должно работать?   -  person Peter Brown    schedule 21.08.2014
comment
В этом коде нет механизма блокировки, который заставлял бы пользователя извлекаться заранее.   -  person Kingpin2k    schedule 21.08.2014
comment
@ Kingpin2k верно, в этом весь смысл этого поста. :)   -  person Peter Brown    schedule 21.08.2014
comment
Да, но я говорю, что не было ни одного, когда вы использовали бета-версию 8.   -  person Kingpin2k    schedule 21.08.2014
comment
Итак, я прочесал простой материал аутентификации, и похоже, что общий шаблон, который они используют, чтобы подключиться к маршруту приложения перед перехватом модели и перенаправить на маршрут входа, если пользователь не аутентифицирован. Используете ли вы их миксин маршрута приложения?   -  person Kingpin2k    schedule 21.08.2014
comment
@ Kingpin2k Я использую миксин маршрута приложения в своем контроллере входа в систему. Я использовал простую аутентификацию в нескольких приложениях и раньше не сталкивался с этой проблемой, поэтому кажется странным, что обновление изменило бы ситуацию.   -  person Peter Brown    schedule 22.08.2014


Ответы (3)


Я делаю что-то подобное, и у меня нет этой проблемы с бета-версией 9. Я бы, возможно, попробовал реализовать эту логику в инициализаторе, чтобы вы могли запустить ее до инициализации простой аутентификации.

import Ember from 'ember';                               
import Session from 'simple-auth/session';               
import Authorizer from 'myapp/authorizers/custom';

export default {
  name: 'simple-auth-config',       
  before: 'simple-auth',            
  initialize: function(container) { 
    container.register('authorizer:custom', Authorizer);                                

    window.ENV = window.ENV || {};                                                      
    window.ENV['simple-auth'] = {                                                       
      authorizer: 'authorizer:custom',                                                  
      crossOriginWhitelist: [MyappENV.API_HOST]
    };                                                                                  

    window.ENV['simple-auth-oauth2'] = {                                                
      serverTokenEndpoint: MyappENV.API_HOST + '/token'                             
    };                                                                                  

    Session.reopen({                                                                    
      currentUser: function() {                                                         
        var userId = this.get('user_id');                                               
        if (!Ember.isEmpty(userId)) {                                                   
          return container.lookup('store:main').find('user', userId);                   
        }                                                                               
      }.property('user_id')                                                             
    });
  }
}                                                                                 

```

person Chris Ball    schedule 21.08.2014
comment
Спасибо за ответ. Похоже, есть пара различий между тем, что вы используете, и тем, что есть у меня. Вы используете property('user_id') для наблюдения за изменением, а я использую observes('user_id'). Вы также используете собственный авторизатор, а я использую простой авторизатор авторизации: oauth2-bearer. Я собираюсь еще немного покопаться, чтобы увидеть, влияют ли эти различия на бета-версию 8 и бета-версию 9. - person Peter Brown; 22.08.2014
comment
Итак, выполнение той же логики в инициализаторе, который запускается до того, как код simpleauth не устранил проблему? Все, что делает мой пользовательский авторизатор, — это устанавливает заголовок авторизации ajax так, как ожидает Rails. Если бы вы вообще не получали заголовки аутентификации, я бы обвинил авторизатора, но проблема, которую вы описываете, заключается в том, что вызов поиска происходит после других вызовов. Определенно было бы очень странно, если бы виновником было свойство против наблюдателей. - person Chris Ball; 22.08.2014
comment
Попробую на выходных, когда будет свободное время. - person Peter Brown; 23.08.2014
comment
Наконец-то у меня появилась возможность попробовать это, и мне не повезло. Я не уверен, что происходит, но опубликовал ответ, который решил мою проблему. Спасибо за предложение! - person Peter Brown; 31.08.2014

Если вам нужно убедиться, что пользователь успешно загрузился до того, как будут сделаны какие-либо другие запросы API, вам нужно будет добавить собственный инициализатор, который откладывает готовность и продвигает готовность только после того, как пользователь успешно загрузился:

// app/initializers/session-user.js
export default {
  name:       'session-user',       
  after:      'simple-auth',            
  initialize: function(container, application) { 
    var session = container.lookup('simple-auth-session:main');
    if (session.get('isAuthenticated')) {
      application.deferReadiness();
      session.get('currentUser').then(function() {
        application.advanceReadiness();
      }, function() {
        //handle error...
      });
    }
  }
}
person marcoow    schedule 01.09.2014
comment
Кажется, это тоже не работает для меня. Если я обновлю приложение при выходе из системы, код запустится, а isAuthenticated будет ложным. Когда я вхожу в систему, код больше не запускается. Я подозреваю, что это потому, что он находится в инициализаторе. Нужно ли привязывать наблюдателя, который следит за свойством isAuthenticated? - person Peter Brown; 01.09.2014
comment
В случае, когда сеанс не аутентифицируется при запуске приложения, а затем аутентифицируется, я не знаю ни одного механизма, который позволил бы вам блокировать все запросы Ember Data до тех пор, пока текущий пользователь не будет загружен - возможно, вы можете заблокировать цикл выполнения как-то. Но это что-то. Я бы не советовал вам это делать. Вы также можете загрузить текущего пользователя в средство проверки подлинности и разрешить его только после успешной загрузки, чтобы сеанс не прошел проверку подлинности раньше. - person marcoow; 01.09.2014

Попробовав все возможные комбинации, которые я мог придумать, единственное, что сработало для меня, - это получить текущего пользователя из сеанса в маршруте приложения. Это кажется довольно хакерским, но я мог бы поэкспериментировать позже, чтобы увидеть, происходит ли что-то еще.

приложение/маршруты/application.js:

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

export default Ember.Route.extend(ApplicationRouteMixin, {
  model: function() {
    if (this.get('session.user_id')) {
      return this.get('session.currentUser');
    }
  }
});
person Peter Brown    schedule 31.08.2014