Подсистемы регистрации, аутентификации и авторизации пользователей нужны практически любому веб-проекту. К созданию таких подсистем можно подойти с разных сторон. Например — воспользоваться специализированными библиотеками. Сегодня мы хотим поделиться с вами переводом статьи Элвина Креспо, программиста из Echobind, который рассказывает о библиотеке ember-simple-auth.
По его словам, эта библиотека, предназначенная для организации аутентификации и авторизации, занимает достойное место в арсенале инструментов, которыми пользуются в компании для разработки веб-систем, основанных на Ember. В этом материале Элвин говорит о том, как интегрировать библиотеку в проект и создать подсистему регистрации пользователей сайта.
Для начала создадим новое Ember-приложение:
После выполнения этой команды вы должны увидеть следующее:
Как видите, я пользуюсь NPM, всё работает как надо, поэтому прошу меня за это не критиковать.
Перейдём в директорию нового приложения:
Установим
После выполнения этой команды система должна сообщить об успешной установке библиотеки:
С установкой мы разобрались, как видите, тут никаких сложностей нет. Теперь займёмся настройкой приложения.
Для начала создадим адаптер приложения:
Здесь мы воспользовались генератором для того, чтобы создать адаптер уровня приложения, применяемый по умолчанию. В результате будет создан следующий файл:
Тут нам нужно внести некоторые изменения, приведя этот файл к следующему виду:
Здесь мы импортировали адаптер
Здесь, во-первых, в качестве
Аутентификатор аутентифицирует сессию. Для этого может быть использована, например, отправка набора учётных данных серверу и получение от него токена доступа, или инициация аутентификации с использованием внешнего провайдера вроде Facebook.
Если в двух словах, то аутентификатор применяется для аутентификации сессии с помощью переданных ему учётных данных. Тут мы будем использовать OAuth2PasswordGrantAuthenticator, что даёт возможность выполнять аутентификацию с помощью идентификатора (имя пользователя, адреса электронной почты, и так далее) и пароля.
Для того, чтобы создать аутентификатор, воспользуемся следующей командой:
В ответ система выведет следующее:
В ходе выполнения вышеописанной команды будет создан файл
Теперь нам нужно задать свойство serverTokenEndpoint. Какую роль оно играет?
Это — конечная точка на сервере, к которой отправляют запросы на аутентификацию и на обновление токена.
Настроим конечную точку всё в том же файле
Тут мы формируем необходимое нам свойство
В
Авторизаторы используют данные сессии, полученные аутентификатором в ходе аутентификации сессии, для формирования данных авторизации, которые затем, например, могут быть встроены в последующие сетевые запросы.
Смысл этого всего заключается в том, что после завершения аутентификации авторизатор использует данные сессии для формирования данных авторизации, используемых в запросах. В нашем примере это приведёт к формированию такого заголовка:
К счастью, библиотека
Нам нужно лишь выполнить такую команду:
После выполнения команды мы увидим следующее:
В результате будет создан файл, расположенный по пути
После того, как настройка подсистем аутентификации и авторизации завершена, можно воспользоваться всем этим в приложении.
Сначала нужно создать маршрут, который обеспечивает регистрацию в системе:
В ответ на эту команду будет выдано следующее:
Откроем созданный шаблон формы регистрации (
Тут создана простая форма с полями
Выше мы всего лишь добавили действие
В действии
Служба сессии предоставляет доступ к текущей сессии, а также методы для её аутентификации, признания недействительной, и так далее. Это — главный интерфейс к функционалу Ember Simple Auth, которым могут пользоваться приложения.
Учитывая это, затем мы вызываем метод authenticate. Мы передаём этому методу аутентификатор, который мы хотим использовать, в нашем случае
Обратите внимание на то, что если вы не пользовались конструкцией
Теперь нам осталось лишь определить модель
sourceТакое вряд ли кого порадует, поэтому займёмся моделью.
Мы создадим довольно простую модель
Выполнив эту команду, увидим следующее:
Созданный этой командой файл модели
Теперь всё готово к испытаниям.
Для того, чтобы посмотреть на то, что мы только что сделали, в действии, надо запустить приложение. Но прежде чем это сделать, уберём стандартную страницу приветствия. Откроем файл
Теперь запустим сервер:
После этого надо перейти по адресу
Вот пример работы с только что созданной клиентской частью системы аутентификации:
В этом материале мы интегрировали в Ember-приложение клиентскую часть системы регистрации, аутентификации и авторизации пользователей. Теперь осталось лишь подключить всё это к API. Как вариант, можно сымитировать конечную точку в ember-cli-mirage. Однако, мы собираемся выйти на реально работающее веб-приложение, поэтому в следующий раз продолжим работу над проектом с применением Elixir/Phoenix и Guardian.
Уважаемые читатели! Как вы создаёте подсистемы аутентификации для веб-приложений?
По его словам, эта библиотека, предназначенная для организации аутентификации и авторизации, занимает достойное место в арсенале инструментов, которыми пользуются в компании для разработки веб-систем, основанных на Ember. В этом материале Элвин говорит о том, как интегрировать библиотеку в проект и создать подсистему регистрации пользователей сайта.
Установка ember-simple-auth
Для начала создадим новое Ember-приложение:
ember new auth-example-frontend
После выполнения этой команды вы должны увидеть следующее:
? ember new auth-example-frontend
installing app
create .editorconfig
create .ember-cli
create .eslintrc.js
create .travis.yml
create .watchmanconfig
create README.md
create app/app.js
create app/components/.gitkeep
create app/controllers/.gitkeep
create app/helpers/.gitkeep
create app/index.html
create app/models/.gitkeep
create app/resolver.js
create app/router.js
create app/routes/.gitkeep
create app/styles/app.css
create app/templates/application.hbs
create app/templates/components/.gitkeep
create config/environment.js
create config/targets.js
create ember-cli-build.js
create .gitignore
create package.json
create public/crossdomain.xml
create public/robots.txt
create testem.js
create tests/.eslintrc.js
create tests/helpers/destroy-app.js
create tests/helpers/module-for-acceptance.js
create tests/helpers/resolver.js
create tests/helpers/start-app.js
create tests/index.html
create tests/integration/.gitkeep
create tests/test-helper.js
create tests/unit/.gitkeep
create vendor/.gitkeep
NPM: Installed dependencies
Как видите, я пользуюсь NPM, всё работает как надо, поэтому прошу меня за это не критиковать.
Перейдём в директорию нового приложения:
cd auth-example-frontend
Установим
ember-simple-auth
:ember install ember-simple-auth
После выполнения этой команды система должна сообщить об успешной установке библиотеки:
? ember install ember-simple-auth
NPM: Installed ember-simple-auth
Installed addon package.
С установкой мы разобрались, как видите, тут никаких сложностей нет. Теперь займёмся настройкой приложения.
Настройка адаптера
Для начала создадим адаптер приложения:
? ember g adapter application
installing adapter
create app/adapters/application.js
installing adapter-test
create tests/unit/adapters/application-test.js
Здесь мы воспользовались генератором для того, чтобы создать адаптер уровня приложения, применяемый по умолчанию. В результате будет создан следующий файл:
// auth-example-frontend/app/adapters/application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
});
Тут нам нужно внести некоторые изменения, приведя этот файл к следующему виду:
// auth-example-frontend/app/adapters/application.js
import JSONAPIAdapter from 'ember-data/adapters/json-api';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
import config from 'my-app/config/environment';
export default JSONAPIAdapter.extend(DataAdapterMixin, {
host: config.apiUrl,
namespace: config.apiNamespace,
authorizer: 'authorizer:application'
});
Здесь мы импортировали адаптер
JSONAPIAdapter
, расширили его с помощью DataAdapterMixin
и добавили несколько свойств. В частности, значения, которые записываются в host
и namespace
хранятся в файле config/environment.js
, который мы тоже импортируем. В нём есть следующий код, отвечающий за интересующие нас значения:let ENV = {
...
apiNamespace: 'api',
apiUrl: null
};
Здесь, во-первых, в качестве
apiNamespace
указана строка api
, что влияет на формирование путей вида http://localhost:4000/api/users
. При этом apiURL
мы будем задавать с помощью опции proxy
в ember-cli
, например, так: ember s --proxy http://localhost:4000
Настройка аутентификатора
Аутентификатор аутентифицирует сессию. Для этого может быть использована, например, отправка набора учётных данных серверу и получение от него токена доступа, или инициация аутентификации с использованием внешнего провайдера вроде Facebook.
Если в двух словах, то аутентификатор применяется для аутентификации сессии с помощью переданных ему учётных данных. Тут мы будем использовать OAuth2PasswordGrantAuthenticator, что даёт возможность выполнять аутентификацию с помощью идентификатора (имя пользователя, адреса электронной почты, и так далее) и пароля.
Для того, чтобы создать аутентификатор, воспользуемся следующей командой:
ember g authenticator oauth2 --base-class=oauth2
В ответ система выведет следующее:
? ember g authenticator oauth2 --base-class=oauth2
installing authenticator
create app/authenticators/oauth2.js
В ходе выполнения вышеописанной команды будет создан файл
oauth2.js
:// auth-example-frontend/app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';
export default OAuth2PasswordGrant.extend({
});
Теперь нам нужно задать свойство serverTokenEndpoint. Какую роль оно играет?
Это — конечная точка на сервере, к которой отправляют запросы на аутентификацию и на обновление токена.
Настроим конечную точку всё в том же файле
oauth2.js
:// auth-example-frontend/app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';
import config from 'my-app/config/environment';
const host = config.apiUrl || '';
const namespace = config.apiNamespace;
const serverTokenEndpoint = [ host, namespace, 'token' ];
export default OAuth2PasswordGrant.extend({
serverTokenEndpoint: serverTokenEndpoint.join('/')
});
Тут мы формируем необходимое нам свойство
serverTokenEndpoint
, объединяя строковые константы host
и namespace
со строкой token
. В результате, например, если у нас есть следующее:host = 'http://localhost:4000'
namespace = 'api'
token = 'token'
В
serverTokenEndpoint
окажется такая строка:http://localhost:4000/api/token
Настройка авторизатора
Авторизаторы используют данные сессии, полученные аутентификатором в ходе аутентификации сессии, для формирования данных авторизации, которые затем, например, могут быть встроены в последующие сетевые запросы.
Смысл этого всего заключается в том, что после завершения аутентификации авторизатор использует данные сессии для формирования данных авторизации, используемых в запросах. В нашем примере это приведёт к формированию такого заголовка:
Authorization: Bearer s0m3tok3n1
К счастью, библиотека
ember-simple-auth
упрощает настройку всего этого. Мы будем использовать класс OAuth2BearerAuthorizer, так как он, без особых усилий с нашей стороны, позволяет сформировать вышеописанный заголовок.Нам нужно лишь выполнить такую команду:
ember g authorizer application --base-class=oauth2
После выполнения команды мы увидим следующее:
? ember g authorizer application --base-class=oauth2
installing authorizer
create app/authorizers/application.js
В результате будет создан файл, расположенный по пути
app/authorizers/application.js
:// auth-example-frontend/app/authorizers/application.js
import OAuth2Bearer from 'ember-simple-auth/authorizers/oauth2-bearer';
export default OAuth2Bearer.extend({
});
Подключение ember simple auth к приложению
После того, как настройка подсистем аутентификации и авторизации завершена, можно воспользоваться всем этим в приложении.
?Создание маршрута для регистрации в системе
Сначала нужно создать маршрут, который обеспечивает регистрацию в системе:
ember g route sign-up
В ответ на эту команду будет выдано следующее:
? ember g route sign-up
installing route
create app/routes/sign-up.js
create app/templates/sign-up.hbs
updating router
add route sign-up
installing route-test
create tests/unit/routes/sign-up-test.js
Откроем созданный шаблон формы регистрации (
sign-up.hbs
) и приведём его к такому виду:<form {{action "onSignUp" email password on="submit"}}>
<div>
<label>Email</label>
{{input type="email" value=email}}
</div>
<div>
<label>Password</label>
{{input type="password" value=password}}
</div>
<button type="submit">Sign Up</button>
</form>
Тут создана простая форма с полями
email
и password
. Когда пользователь щёлкает по кнопке Sign Up —
мы вызываем действие onSignUp
, передавая ему введённые адрес электронной почты и пароль. Определим это действие:// auth-example-frontend/routes/sign-up.js
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
const AUTHENTICATOR = 'authenticator:oauth2';
export default Route.extend({
session: service(),
actions: {
async onSignUp(email, password) {
let attrs = { email, password };
let user = this.store.createRecord('user', attrs);
await user.save();
let session = this.get('session');
await session.authenticate(AUTHENTICATOR, email, password);
}
}
});
Выше мы всего лишь добавили действие
onSignUp
в маршрут. Если вы не знакомы с тем, как в Ember работают события, то, учитывайте, что действие onSignUp
, вызванное в шаблоне, задействует контроллер, а затем маршрут. Так как мы не определяем действие в контроллере, его обработает маршрут.В действии
onSignUp
мы получаем email
и password
, поэтому мы используем эти данные для создания учётной записи пользователя. Затем сохраним эту учётную запись и получим службу сессии. Служба сессии является частью ember-simple-auth
, вот её описание:Служба сессии предоставляет доступ к текущей сессии, а также методы для её аутентификации, признания недействительной, и так далее. Это — главный интерфейс к функционалу Ember Simple Auth, которым могут пользоваться приложения.
Учитывая это, затем мы вызываем метод authenticate. Мы передаём этому методу аутентификатор, который мы хотим использовать, в нашем случае
authenticator:oauth2
, а также, в виде отдельных аргументов, пароль и адрес электронной почты.Обратите внимание на то, что если вы не пользовались конструкцией
async/await
в вашем проекте, то вполне можно работать и без неё. Вы можете легко убрать async/await
из вышеприведённого кода и использовать конструкцию then/catch/finally
для разрешения промисов. Если вам интересно узнать подробности об использовании async/await
в ваших проектах, взгляните на этот материал.Теперь нам осталось лишь определить модель
user
. Если этого не сделать, мы столкнёмся со следующей неприятной ошибкой:sourceТакое вряд ли кого порадует, поэтому займёмся моделью.
?Определение модели user
Мы создадим довольно простую модель
user
. Она будет содержать лишь адрес электронной почты и пароль. Создадим её, запустив следующий генератор:ember g model user email:string password:string
Выполнив эту команду, увидим следующее:
? ember g model user email:string password:string
installing model
create app/models/user.js
installing model-test
create tests/unit/models/user-test.js
Созданный этой командой файл модели
user.js
надо привести к такому виду:// auth-example-frontend/models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
email: DS.attr('string'),
password: DS.attr('string')
});
Теперь всё готово к испытаниям.
Тестирование системы аутентификации
Для того, чтобы посмотреть на то, что мы только что сделали, в действии, надо запустить приложение. Но прежде чем это сделать, уберём стандартную страницу приветствия. Откроем файл
package.json
и удалим из него следующее:"ember-welcome-page": "^3.0.0",
Теперь запустим сервер:
ember s
После этого надо перейти по адресу
http://localhost:4200/sign-up
.Вот пример работы с только что созданной клиентской частью системы аутентификации:
Итоги
В этом материале мы интегрировали в Ember-приложение клиентскую часть системы регистрации, аутентификации и авторизации пользователей. Теперь осталось лишь подключить всё это к API. Как вариант, можно сымитировать конечную точку в ember-cli-mirage. Однако, мы собираемся выйти на реально работающее веб-приложение, поэтому в следующий раз продолжим работу над проектом с применением Elixir/Phoenix и Guardian.
Уважаемые читатели! Как вы создаёте подсистемы аутентификации для веб-приложений?
websiteproduct
Уважаемый автор, вероятно теги исходного кода ошибки при отсутствующей модели user были проставлены с ошибкой, просто "source" написано. Судя по статье, ember достаточно прост в реализации определенного функционала. Спасибо за статью