我们正在使用两个ember应用程序,每个应用程序运行不同版本的ember和ember-simple-auth,并且希望让ember-simple-auth与这两个版本一起使用。
旧应用
新应用
我们尝试更改旧版本的会话API,以便正确存储访问权限和刷新令牌,以便新应用可以使用它。
到目前为止,我们已尝试重写setup
和updateStore
方法以使用authenticated
嵌套对象,但仍然遇到问题。
答案 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版本(这是完全新鲜和新代码库)的事实推动我们走走这条路。