获得两个版本的ember-simple-auth可以很好地协同工作

时间:2016-03-23 19:15:06

标签: ember.js ember-simple-auth

我们正在使用两个ember应用程序,每个应用程序运行不同版本的ember和ember-simple-auth,并且希望让ember-simple-auth与这两个版本一起使用。

旧应用

  • Ember 1.8.1
  • Ember-simple-auth 0.7.3

新应用

  • Ember 2.3.1
  • Ember-simple-auth 1.0.1
  • 使用cookie会话商店

我们尝试更改旧版本的会话API,以便正确存储访问权限和刷新令牌,以便新应用可以使用它。

到目前为止,我们已尝试重写setupupdateStore方法以使用authenticated嵌套对象,但仍然遇到问题。

1 个答案:

答案 0 :(得分:3)

免责声明 - Patrick Berkeley和我一起工作。我发现这个问题之后我们找到了一个解决方案。

为了使1.0.3版本的ember-simple-auth的cookie存储可以很好地与1.0.0版本一起使用,我们必须规范化应用程序中的cookie格式化方式。几个关键位置的版本,主要以session对象为中心(the 0.7.3 session是一个ObjectProxy,可以在消费应用程序中进行扩展,以创建自己的自定义会话)。

我们需要覆盖的方法,以传递给cookie存储的数据结构为中心,以及在恢复会话时返回的内容。关键区别在于版本0.7.3,access_token等存储在会话的content对象属性的顶层。用1.0.0。这嵌套在内容中的另一个对象内,属性名称为authenticated。因此,我们需要确保在我们假设在顶级设置或获取access_token的任何地方,我们应该更深层次地检索一个级别。考虑到这一点,我们在自定义session对象中重写了这些方法:



// alias access_token to point to new place
access_token: Ember.computed.alias('content.authenticated.access_token'),

// overridden methods to handle v2 cookie structure
restore: function() {
  return new Ember.RSVP.Promise((resolve, reject) => {
    const restoredContent = this.store.restore();
    const authenticator   = restoredContent.authenticated.authenticator;

    if (!!authenticator) {
      delete restoredContent.authenticated.authenticator;
      this.container.lookup(authenticator).restore(restoredContent.authenticated).then(function(content) {
        this.setup(authenticator, content);
        resolve();
      }, () => {
        this.store.clear();
        reject();
      });
    } else {
      this.store.clear();
      reject();
    }
  });
},

updateStore: function() {
  let data = this.content;
  if (!Ember.isEmpty(this.authenticator)) {
    Ember.set(data, 'authenticated', Ember.merge({ authenticator: this.authenticator }, data.authenticated || {}));
  }

  if (!Ember.isEmpty(data)) {
    this.store.persist(data);
  }
},

setup(authenticator, authenticatedContent, trigger) {
  trigger = !!trigger && !this.get('isAuthenticated');

  this.beginPropertyChanges();
  this.setProperties({
    isAuthenticated: true,
    authenticator
  });
  Ember.set(this, 'content.authenticated', authenticatedContent);
  this.bindToAuthenticatorEvents();
  this.updateStore();
  this.endPropertyChanges();

  if (trigger) {
    this.trigger('sessionAuthenticationSucceeded');
  }
},

clear: function(trigger) {
  trigger = !!trigger && this.get('isAuthenticated');

  this.beginPropertyChanges();
  this.setProperties({
    isAuthenticated: false,
    authenticator:   null
  });
  Ember.set(this.content, 'authenticated', {});
  this.store.clear();
  this.endPropertyChanges();

  if (trigger) {
    this.trigger('sessionInvalidationSucceeded');
  }
},

bindToStoreEvents: function() {
  this.store.on('sessionDataUpdated', (content) => {
    const authenticator = content.authenticated.authenticator;

    this.set('content', content);

    if (!!authenticator) {
      delete content.authenticated.authenticator;
      this.container.lookup(authenticator).restore(content.authenticated).then((content) => {
        this.setup(authenticator, content, true);
      }, () => {
        this.clear(true);
      });
    } else {
      this.clear(true);
    }
  });
}.observes('store'),




这使我们大部分都在那里。我们只需要确保我们使用的身份验证器名称与1.0.0上的名称匹配。我们需要通过初始化程序将我们的身份验证器重命名为'simple-auth-authenticator:oauth2-password-grant',而不是'authenticator:oauth2'。这可确保具有较新版本的应用程序能够在cookie会话数据更改时处理正确的身份验证器事件。初始化器逻辑很简单:

import OAuth2 from 'simple-auth-oauth2/authenticators/oauth2';

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

  initialize: function(container) {
    container.register('authenticator:oauth2', OAuth2);
  }
};

以上内容满足了我们的需求 - 我们可以使用ember-simple-auth 0.7.3登录应用程序并将cookie会话存储并正确格式化,以便由另一个应用程序在ember-simple-auth 1.0.0上处理。

理想情况下,我们只是根据业务需求更新应用程序的Ember和Ember Simple Auth版本,以及我们希望将精力集中在v2版本(这是完全新鲜和新代码库)的事实推动我们走走这条路。