Отказ от ответственности - Патрик Беркли и я работаем вместе. Мы нашли решение после публикации этого вопроса, который, как я полагал, я бы поделился.
Для того, чтобы версия файла cookie ember-simple-auth версии 0.7.3 играла хорошо с версией 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);
}
};
Вышеприведенные удовлетворяет наш needs- мы можем войти в приложение, используя уголек-простого-авторизацию 0.7.3, а сеанс cookie хранится и отформатирован должным образом для обработки другим приложением на ember-simple-auth 1.0.0.
В идеале мы бы просто обновили версии приложения Ember и Ember Simple Auth, хотя бизнес-потребности и тот факт, что мы хотели сосредоточить наши усилия на версиях v2 (которые являются абсолютно новыми и новыми базами кода), побудили нас к пойдите по этому пути.
ESA 1.0 и <1.0 используют разные форматы сеансов. Любая версия не будет работать с данными, сгенерированными другим. Ваш прецедент может (и должен), скорее всего, быть решен лучше и чище. Можете ли вы более подробно объяснить, чего вы пытаетесь достичь? – marcoow
Спасибо @marcoow. Наша цель - синхронизация сеанса, если два приложения открыты в одном браузере, но разные вкладки. Сейчас у нас это работает. Но одна икота - если мы выйдем из приложения с новой версией ESA, вкладка браузера со старой версией ESA не вызовет ['syncData'] (https://github.com/simplabs/ember-simple-auth /blob/0.7.3/packages/ember-simple-auth-cookie-store/lib/simple-auth-cookie-store/stores/cookie.js#L174-L184) ровно 60 секунд, тогда сессия истекла там слишком. Есть идеи? –