несколько маршрутов входа с использованием ember-cli-simple-auth

Я пытаюсь настроить базовое приложение ember-cli, используя аутентификацию через ember-cli-simple-auth, и хочу иметь выделенную страницу входа «гость» и другую страницу входа «администратора» (авторизацию на разные serverTokenEnpoint's).

У меня работает «гостевая» страница, т. е. если пользователь пытается перейти на защищенный маршрут (страницу), он перенаправляется на маршрут по умолчанию /login и может войти в систему в порядке.

Чего я не могу понять, так это того, как сделать так, чтобы пользователь, просматривающий маршрут /admin/xyz, затем перенаправлялся (используя /admin/login, что, в свою очередь, будет выполнять аутентификацию в другой serverTokenEnpoint по умолчанию.

Может ли кто-нибудь указать мне в правильном направлении для достижения вышеизложенного?

Спасибо.

пример защищенного «гостевого» файла маршрута выглядит так:

ФАЙЛ: /app/routes/protected.js

import Ember from 'ember';

import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin);

И конфиги окружения содержат:

ФАЙЛ: /app/config/environment.js

ENV['simple-auth'] = {
    authorizer: 'simple-auth-authorizer:oauth2-bearer',
    store: 'simple-auth-session-store:local-storage',
    crossOriginWhitelist: ['http://www.domain.com/token',
                         'http://www.domain.com'
   ]
};

Я даже пытался переопределить authenticationRoute по умолчанию в моем файле /app/routes/admin.js, как показано ниже, но это не сработало:

import Ember from 'ember';

import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin,{
    authenticationRoute: 'admin.login'
});

Итак, чтобы упростить процесс по предложению Марко, у меня теперь есть:

Примечание. В данный момент это не работает.

Это использует ember-cli со следующим выводом firebug:

AuthenticatorBase A (unknown mixin)  ***<- IS this expected????***
CustomAuthenticator B (unknown mixin)
DEBUG: -------------------------------
DEBUG: Ember                       : 1.7.0
DEBUG: Ember Data                  : 1.0.0-beta.9
DEBUG: Handlebars                  : 1.3.0
DEBUG: jQuery                      : 1.11.1
DEBUG: Ember Simple Auth           : 0.6.4
DEBUG: Ember Simple Auth OAuth 2.0 : 0.6.4
DEBUG: -------------------------------

и если я верну свой код ручного переопределения обратно, см. предыдущий ответ, он будет работать, но, поскольку я хочу использовать ту же аутентификацию oauth2 только для другого URL-адреса, мне нравится идея просто переопределить TokenEndpoint с пользовательским аутентификатором.

файл: app/initializers/simple-auth-admin.js

import AuthenticatorBase from 'simple-auth-oauth2/authenticators/oauth2';
var CustomAuthenticator = AuthenticatorBase.extend({
    serverTokenEndpoint:            AppchatENV['simple-auth-admin'].serverTokenEndpoint,
    serverTokenRevokationEndpoint:  AppchatENV['simple-auth-admin'].serverRevokationTokenEndpoint,
    refreshAccessTokens:            AppchatENV['simple-auth-admin'].refreshAccessTokens
});
console.log("AuthenticatorBase A ",AuthenticatorBase);
console.log("CustomAuthenticator B ",CustomAuthenticator);

export default {
    name:   'simple-auth-admin',
    before: 'simple-auth',
    initialize: function(container) {
        container.register('simple-auth-authenticator:admin', CustomAuthenticator);
    }
};

Но приведенное выше показывает ошибку «AuthenticatorBase A (неизвестный миксин)».

а затем в файле: app/controllers/admin/login.js

import Ember from 'ember';
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:admin'
}

а по конфигам...

файл: config/environment.js

ENV['simple-auth-admin'] = {
    serverTokenEndpoint: "http://www.domain.com/admintoken",
    serverTokenRevokationEndpoint: "http://www.domain.com/admintoken/revoke",
    refreshAccessTokens: true
  };

РЕДАКТИРОВАТЬ:

поэтому, установив: в файле: app/initializers/simple-auth-admin.js

import AuthenticatorBase from 'simple-auth-oauth2/authenticators/oauth2';
var CustomAuthenticator = AuthenticatorBase.extend({
    serverTokenEndpoint:            MyappENV['simple-auth-admin'].serverTokenEndpoint,
    serverTokenRevokationEndpoint:  MyappENV['simple-auth-admin'].serverRevokationTokenEndpoint,
    refreshAccessTokens:            MyappENV['simple-auth-admin'].refreshAccessTokens
});

console.log("AuthenticatorBase.serverTokenEndpoint =",AuthenticatorBase.serverTokenEndpoint);
console.log("CustomAuthenticator.serverTokenEndpoint =",CustomAuthenticator.serverTokenEndpoint);
console.log("MyappENV['simple-auth-admin'].serverTokenEndpoint =  ",MyappENV['simple-auth-admin'].serverTokenEndpoint);

export default {
    name:   'simple-auth-admin',
    before: 'simple-auth',
    initialize: function(container) {
        container.register('simple-auth-authenticator:admin', CustomAuthenticator);
        console.log("[at container.register] CustomAuthenticator.serverTokenEndpoint =  ",CustomAuthenticator.create().get('serverTokenEndpoint'));

    }
};

Я получаю вывод:

AuthenticatorBase.serverTokenEndpoint = undefined
CustomAuthenticator.serverTokenEndpoint = undefined
MyappENV['simple-auth-admin'].serverTokenEndpoint =  http://www.domain.com/oauth2/admintoken
[at container.register] CustomAuthenticator.serverTokenEndpoint = http://www.domain.com/oauth2/admintoken

Я неправильно понимаю, что делает AuthenticatorBase.extend()? Я думал, это позволит вам переопределить некоторые переменные или функции?

РЕДАКТИРОВАТЬ 2:

файл: app/controllers/admin/login.js

import Ember from 'ember';
var $ = Ember.$;
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:admin',
    init: function(){
        console.log('INIT LOGIN CONTROLLER', this.get('session'));
        this._super();
    },
    actions: {
        authenticate: function() { // (data)
            console.log("LoginController clicked");
            $('#nameBtn').ladda().ladda('start');
            console.log(this.get('session'));

            console.log('this.authenticator = ', this.authenticator);
            var _this = this;
            this._super().then(null, function(data) {
                console.log('LOGIN GOT BACK: ', data);
                $('#nameBtn').ladda().ladda('stop');
                    if(data.error !== undefined && data.error !== "") {
                    _this.set('data', {error: data.error});
                }
            });
        }
    }
});

Это приводит к ajax-адресу www.domain.com/token, а не к ожидаемому www.domain.com/admintoken.


person ShopApps.co.uk    schedule 04.09.2014    source источник


Ответы (3)


Хорошо, после большого количества кодирования в кругах, проб и ошибок и с большой помощью от:

https://github.com/simplabs/ember-simple-auth/blob/master/examples/6-custom-server.html

вот так я добился того, чего хотел...

1) Настройте enpoints как переменные в файле среды (simple-auth-admin — это имя, которое я выбрал для своего аутентификатора администратора)

Файл: /app/config/environment.js

ENV['simple-auth-admin'] = {
    serverTokenEndpoint: "http://www.domain.com/admintoken",
    serverTokenRevokationEndpoint: "http://www.domain.com/admintoken/revoke",
    refreshAccessTokens: true
};

2) Создайте фактический аутентификатор как переопределение в инициализаторе. Примечание: в этом случае CustomAuthorizer фактически не используется, и убедитесь, что вы заменили AppNameENV на имя вашего приложения, поэтому, если ваше приложение называлось bob, оно быть BobENV.

Файл: /app/initializers/simple-auth-admin.js

import Ember from 'ember';
import AuthenticatorBase from 'simple-auth/authenticators/base';
import AuthorizerBase from 'simple-auth/authorizers/base';

var CustomAuthorizer = AuthorizerBase.extend({
authorize: function(jqXHR, requestOptions) {
    if (this.get('session.isAuthenticated') && !Ember.isEmpty(this.get('session.token'))) {
        jqXHR.setRequestHeader('Authorization', 'Token: ' + this.get('session.token'));
    }
}
});

var CustomAuthenticator = AuthenticatorBase.extend({
tokenEndpoint: window.AppNameENV['simple-auth-admin'].serverTokenEndpoint,
tokenRevokationEndpoint: window.AppNameENV['simple-auth-admin'].serverRevokationTokenEndpoint,
refreshAccessTokens: window.AppNameENV['simple-auth-admin'].refreshAccessTokens,
init: function(){
    console.log("CUSOTMM AUTH INIT ",window.AppNameENV['simple-auth-admin'].serverTokenEndpoint);
    this._super();
},
restore: function(data) {
    console.log('AdminAuth - restore');
    return new Ember.RSVP.Promise(function(resolve, reject) {
        if (!Ember.isEmpty(data.token)) {
            resolve(data);
        } else {
            reject();
        }
    });
},
authenticate: function(credentials) {
    console.log('AdminAuth - authenticate',credentials);
    var _this = this;
    return new Ember.RSVP.Promise(function(resolve, reject) {
        Ember.$.ajax({
            url: _this.tokenEndpoint,
            type: 'POST',
            data: JSON.stringify({ grant_type: 'password', username: credentials.identification, password: credentials.password, session: { identification: credentials.identification, password: credentials.password } }),
                    contentType: 'application/json'
                }).then(function(response) {
                    Ember.run(function() {
                        resolve({ token: response.access_token });
                    });
                }, function(xhr, status, error) {
                    var response = JSON.parse(xhr.responseText);
                    Ember.run(function() {
                        reject(response.error);
                    });
                });
        });
    },
    invalidate: function() {
        console.log('AdminAuth - invalidate');
        var _this = this;
        return new Ember.RSVP.Promise(function(resolve) {
            Ember.$.ajax({ url: _this.tokenEndpoint, type: 'DELETE' }).always(function() {
            resolve();
            })
        });
    }
});

export default {
    name:   'simple-auth-admin',
    before: 'simple-auth',
    initialize: function(container) {
        console.log("OVERRIDES : ", window.AppNameENV['simple-auth-admin']);
        container.register('simple-auth-authenticator:admin', CustomAuthenticator);
        container.register('simple-auth-authorizer:admin', CustomAuthorizer);
    }
};

3) Я устанавливаю маршрут перенаправления на admin/login для любых защищенных страниц (этот пример для /admin/dashboard)

Файл: /app/routes/admin/dashboard.js

import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin,{
    authenticationRoute: 'admin.login',
    actions: {
        authenticateSession: function() {
            this.transitionTo(this.authenticationRoute);
        }
    }
});

4) Затем настройте контроллер администратора для использования нового пользовательского аутентификатора.

Файл: /app/controllers/admin/login.js

import Ember from 'ember';
var $ = Ember.$;
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
//import Session from 'simple-auth/session';

export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:admin',
});

Все это кажется немного сложным, когда все, что я действительно хотел сделать, это иметь аутентификацию для /admin/login, указывающую на другую конечную точку сервера. Марко, есть ли способ переопределить только эти переменные и, следовательно, расширить авторизатор simple-auth-oauth2?

person ShopApps.co.uk    schedule 05.09.2014

Конечно, маршруты, которые вы определяете, необходимы.

Поскольку ваш авторизатор и аутентификатор для административной области, похоже, также настроены, они, конечно, также необходимы. Если вы также использовали простые OAuth 2.0 для административной области, вы можете удалить авторизатор и изменить аутентификатор на

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

var CustomAuthenticator = AuthenticatorBase.extend({
  serverTokenEndpoint:           'http://www.domain.com/admintoken',
  serverTokenRevokationEndpoint: 'http://www.domain.com/admintoken/revoke'
});
person marcoow    schedule 05.09.2014
comment
да, это выглядит более прямо вперед. не могли бы вы отредактировать свой ответ: импортировать AuthenticatorBase из «simple-auth-oauth2/authenticators/oauth2»; сейчас просто тестирую и приму это как ответ, если он сработает для меня :) - person ShopApps.co.uk; 06.09.2014
comment
хм, должно быть, я делаю что-то не так, так как serverTokenEndpoint, по-видимому, по умолчанию использует исходный / токен вместо / tokenadmin. Все, что я сделал, это удалил весь мой код CustomAuthenticator в инициализаторе и вместо этого вставил ваше предложение... хм... - person ShopApps.co.uk; 06.09.2014
comment
кроме того, если я выполню console.log CustomAuthenticator (с функцией инициализации экспорта по умолчанию), я получу: TOKENENPOINT (неизвестный миксин). И если я попытаюсь записать в console.log CustomAuthenticator.serverTokenEndpoint, я получу undefined какие-нибудь мысли? - еще раз спасибо за вашу помощь до сих пор. - person ShopApps.co.uk; 06.09.2014
comment
Привет, @marcoow. Мне интересно, есть ли у вас какие-либо мысли о том, почему возникает ошибка неизвестного миксина с предложенным вами ответом? - Спасибо. - person ShopApps.co.uk; 09.09.2014
comment
Можете ли вы опубликовать код вашего пользовательского аутентификатора? - person marcoow; 10.09.2014
comment
Я перестал использовать собственный аутентификатор и просто пытался переопределить конечную точку назначения в соответствии с вашим фрагментом выше, а затем в функции инициализации у меня было просто: container.register('simple-auth-authenticator:admin', CustomAuthenticator); - person ShopApps.co.uk; 10.09.2014
comment
Проблема в том, что если я поставлю console.log(CustomAuthenticator B,CustomAuthenticator); сразу после вашего кода, я получу ошибку неизвестный миксин - person ShopApps.co.uk; 10.09.2014
comment
Вы используете пользовательский аутентификатор, когда существует CustomAuthenticator. Можете ли вы опубликовать код? Также вы используете Ember CLI? - person marcoow; 10.09.2014
comment
Привет, посмотри мой новый ответ с подробным описанием кода, который я сейчас пытаюсь использовать. Еще раз спасибо за любую помощь. - person ShopApps.co.uk; 11.09.2014

Каждый раз, когда Ember Simple Auth принудительно выполняет аутентификацию (обычно когда пользователь получает доступ к аутентифицированному маршруту, а сессия не аутентифицирована), он вызывает authenticateSession действие ApplicationRouteMixin. Лучший вариант, который у вас есть, — переопределить это и каким-то образом решить, переходить ли оттуда на страницу входа администратора или гостя. Если у вас есть, например. ваши пространства имен страниц администратора в маршруте /admin, вы также можете переопределить authenticateSession на AdminRoute и перейти оттуда на страницу входа администратора, в то время как реализация по умолчанию в ApplicationRoute переходит на гостевую страницу входа.

Для аутентификаторов, вероятно, лучше всего использовать аутентификатор OAuth 2.0 по умолчанию с его serverTokenEndpoint для аутентификации гостей и расширить другой аутентификатор от того, который аутентифицирует администратора, против другого serverTokenEndpoint.

person marcoow    schedule 05.09.2014
comment
Спасибо, Марко, у вас есть рекомендуемое место для переопределения или мне просто попробовать /app/routes/admin.js? - person ShopApps.co.uk; 05.09.2014
comment
Конечно, просто определите это в своем маршруте администратора (что эффективно переопределит это действие для всех маршрутов за пределами этого маршрута администратора). - person marcoow; 05.09.2014