Ember Simple Auth — внедрение текущего пользователя в каждый маршрут

Я создаю сайт, используя Ember Simple Auth.

Я выполнил эти инструкции, чтобы попытаться добавить текущий объект пользователя в сеанс. и это сработало, используя этот слегка адаптированный код:

import Ember from 'ember';
import Session from 'simple-auth/session';

export default {
  name: "current-user",
  before: "simple-auth",
  initialize: function(container) {
    Session.reopen({
      setCurrentUser: function() {
        var accessToken = this.get('secure.token');
        var _this = this;
        if (!Ember.isEmpty(accessToken)) {
          return container.lookup('store:main').find('user', 'me').then(function(user) {
            _this.set('content.currentUser', user);
          });
        }
      }.observes('secure.token'),
      setAccount: function() {
        var _this = this;
        return container.lookup('store:main').find('account', this.get('content.currentUser.account.content.id')).then(function(account) {
          _this.set('content.account', account);
        });
      }.observes('content.currentUser'),
    });
  }
};

Однако, используя последнюю версию Ember, я получаю следующее:

УСТАРЕВАНИЕ: lookup был вызван в реестре. initializer API больше не получает контейнер, и вам следует использовать instanceInitializer для поиска объектов из контейнера. См. http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers для более подробной информации.

Я знаю, что мне нужно разделить вышеуказанное на /app/initializers и /app/instance-initializers (согласно примечаниям здесь), но я не совсем уверен, как это сделать.

Конечно, если есть более простой/чистый способ сделать объекты пользователя и учетной записи доступными для каждого маршрута/шаблона, я бы хотел их услышать :)

Спасибо


person Joe Czucha    schedule 16.06.2015    source источник


Ответы (3)


Это работает для меня на:

  • ember-cli: 0.2.7 (ember: 1.12.0, ember-data: 1.0.0-beta.18)
  • ember-cli-простая-аутентификация: 0.8.0-beta.3

Примечание.

  • ember-данные: 1.13. Магазин зарегистрирован в инициализаторе, должен работать как есть
  • Ember-данные: 1.0.0-бета.19. Магазин зарегистрирован в экземпляре-инициализаторе, необходимы некоторые настройки

1) Настроить сеанс

//config/environment.js
ENV['simple-auth'] = {
  session: 'session:custom',
  ...
}

//app/sessions/custom.js
import Session from 'simple-auth/session';

export default Session.extend({

  // here _store is ember-data store injected by initializer
  // why "_store"? because "store" is already used by simple-auth as localStorage
  // why initializer? I tried 
  // _store: Ember.inject.service('store') and got error

  currentUser: function() {
    var userId = this.get('secure.userId');
    if (userId && this.get('isAuthenticated')) {
      return this._store.find('user', userId);
    }
  }.property('secure.userId', 'isAuthenticated')

});

2) Внедрить хранилище в сеанс с помощью инициализатора (иначе find() не сработает)

//app/initializers/session-store
export function initialize(container, application) {
  application.inject('session:custom', '_store', 'store:main')

  // "store:main" is highly dynamic depepeding on ember-data version
  // in 1.0.0-beta.19 (June 5, 2015) => "store:application"
  // in 1.13 (June 16, 2015) => "service:store"
}

export default {
  name: 'session-store',
  after: 'ember-data',
  initialize: initialize
}

3) В шаблоне

{{#if session.isAuthenticated}}
  {{session.currentUser.name}}
{{/if}}

Примечание: это не освобождает вас от устаревания, сгенерированного самим ember-simple-auth.

person artych    schedule 17.06.2015
comment
Фантастический ответ, большое спасибо. Мне пришлось обновить свой собственный Devise::SessionsController, чтобы он возвращал userId вместе с токеном и адресом электронной почты, но в остальном он работал безупречно. - person Joe Czucha; 17.06.2015
comment
Артыч, просто дополнительный вопрос - я могу получить доступ к объектам сеанса в контроллерах, используя this.get('session.currentUser'), но, похоже, это не работает в маршрутах. Должен ли я делать что-то по-другому? Спасибо - person Joe Czucha; 18.06.2015
comment
Не забывайте, что currentUser — это обещание. this.get('session.currentUser').then(function(user) { console.log('user-name', user.get('name')) }); работает на каждом маршруте. (И спасибо за предыдущий комментарий) - person artych; 18.06.2015
comment
Вы также можете пропустить инициализатор, добавив: var _store = this.container.lookup('store:application'); в custom.js. Это также помогает, если ваша _store-переменная не определена (ошибка: find on undefined). - person Toni; 03.08.2015
comment
Пробовал это на Ember: 2.2.0, Ember Data: 2.2.1 и Ember Simple Auth: 1.0.0 и не работал. - person Andrei Stalbe; 04.12.2015

Прежде всего, вы не должны повторно открывать сеанс, а вместо этого использовать пользовательский сеанс (см. этот пример: https://github.com/simplabs/ember-simple-auth/blob/master/examples/4-authentication-account.html#L132) . Также вам следует загружать текущего пользователя не только при установке токена доступа, но и при аутентификации сеанса ('session.get('isAuthenticated')'), что делает ваш код не зависящим от аутентификатора.

Мы надеемся, что предупреждения об устаревании относительно использования реестра в инициализаторе исчезнут в ESA 0.9.0.

person marcoow    schedule 17.06.2015
comment
Спасибо за совет, marcoow, и за всю вашу работу над ember-simple-auth. - person Joe Czucha; 17.06.2015
comment
Привет @marcoow, не могли бы вы обновить ссылку? Или привести новый пример? - person lpinto.eu; 02.01.2016
comment
Вся концепция пользовательских сессий больше не существует с версии 1.0. Вместо этого вы можете просто использовать службу — см. фиктивное приложение в репозитории: github.com/simplabs/ember-simple-auth/tree/master/tests/dummy/ - person marcoow; 05.01.2016
comment
Для всех, кто просматривает ссылку @marcoow, вы также можете увидеть использование службы: github.com/simplabs/ember-simple-auth/blob/master/tests/dummy/ - person noel; 08.01.2016

Вот до и после инициализатора/инициализатора экземпляра, который я сделал на днях.

До

export function initialize( container, application ) {
    var session = Ember.Object.create({
        user:null,
        authorization:null
    });

    application.register('session:main', session, { instantiate: false });
    application.inject('route', 'session', 'session:main');
    application.inject('controller', 'session', 'session:main');
    application.inject('adapter', 'session', 'session:main');
}

После

export function initialize( instance) {
    var session = Ember.Object.create({
        user:null,
        authorization:null
    });

    instance.registry.register('session:main', session, { instantiate: false });
    instance.registry.injection('route', 'session', 'session:main');
    instance.registry.injection('controller', 'session', 'session:main');
    instance.registry.injection('adapter', 'session', 'session:main');
}

Ember Data Stuff

Данные Ember в последних итерациях должны быть получены с использованием store:application

export function initialize(instance) {
    var store = instance.container.lookup('store:application');
    ....
}

export default {
    name: 'socket',
    initialize: initialize,
    after:['ember-data']
};
person Kingpin2k    schedule 16.06.2015