В этом howto будет расказано, каким образом создать среду для разработки веб приложения под Django framework и Ember js (DjEmber).
Права суперпользователя linux нужны только для того, чтобы установить Development Tools и node js, остальные процессы установки делаются под простым пользователем (в этом примере пользователь example).
I. Проект DjEmber - example.com
II. Проект Django - back
III. Проект Ember js - front
- Пользователь - example
- Пользовательская директория /home/example/
- Проект DjEmber - example.com - будет размещаться в /home/example/Projects/example.com/
- Проект Django - back (от слова backend) - будет размещаться в /home/example/Projects/example.com/back/
- Проект Ember - front (от слова frontend) - будет размещаться в /home/example/Projects/example.com/front/
- В Django проекте - back - будет использоваться виртуальное окружение с Python версии 3
- Python 3, установленный из исходников, будет в /home/example/python3/
- Виртуальное окружение для Django проекта - back - /home/example/virtualenv/example.com
- Путь для загруженных программ - /home/example/Downloads/
1. Установка дополнительных программ
$ su -c 'yum groupinstall "Development Tools"'
$ sudo yum install wget
2. Создаю корневой каталог для проекта example.com
$ mkdir -p ~/Projects/example.com
Готовые файлы настроек можно посмотреть и скачать с https://github.com/hairetdin/djember
1. Установка Python 3 в домашнюю директорию пользователя /home/example/python3
- скачиваю исходники стабильной версии python 3, выбираю в https://www.python.org/downloads/source/
$ cd ~/Downloads/
$ wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz
- распаковываю
$ tar xvf Python-3.5.2.tar.xz
- собираю конфигурацию, указываю путь куда будет установен python3 - /home/example/python3/ и устанавливаю
$ cd Python-3.5.2/
$ $ ./configure --prefix=$HOME/python3
$ make
$ make install
- теперь python3 установлен в /home/example/python3/, проверяю
$ ~/python3/bin/python3 -V
Python 3.5.2
2. Создание виртуального окружения для проекта example.com - back (виртуальные окружения у меня находяться в ~/virtualenv)
$ cd ~
$ mkdir -p virtualenv
$ ~/python3/bin/pyvenv ~/virtualenv/example.com
- проверяю работу созданного виртуального окружения - virtualenv/example.com
$ source ~/virtualenv/example.com/bin/activate
в терминале должна появиться строка начинающаяся с - (example.com). Теперь запущу python и посмотрю версию
$ python -V
Python 3.5.2
- деактивация виртуального окружения:
$ deactivate
3. Установка python приложений в виртуальное окружение virtualenv/example.com
- Активирую виртуальное окружение и устанавливаю python приложения
$ source ~/virtualenv/example.com/bin/activate
$ pip install django
$ pip install djangorestframework
$ pip install djangorestframework-jwt
$ pip install django-filter
$ pip install django-cors-headers
Если не будете использовать django-filter, то ставить необязательно.
4. Создаю Django бакэнд проект для example.com
Виртуальное окружение virtualenv/example.com дожно быть активировано.
- перехожу в корень проекта example.com
$ cd ~/Projects/example.com/
- создаю проект back
$ django-admin startproject back
- проверяю созданные Django проект
$ cd ~/Projects/example.com/back/
$ python manage.py runserver
Смотрю в браузере http://127.0.0.1:8000/ - работает, показывает страницу приветствия - "Congratulations on your first Django-powered page."
Хорошо, останавливаю запущенный back проект - Ctrl+C
5. Делаю настройки для ранее установленных python приложений в ~/Projects/example.com/back/back/settings.py
Я для этого я использую редактор Atom, открываю на редактирование settings.py и вношу следующие изменения:
- в INSTALLED_APPS добавляю 'rest_framework' и 'corsheaders'
INSTALLED_APPS = (
...
# external apps
'rest_framework',
'corsheaders',
)
- в MIDDLEWARE_CLASSES добавляю 'corsheaders.middleware.CorsMiddleware',
MIDDLEWARE_CLASSES = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
- добавляю новую конфигурацию для REST_FRAMEWORK
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
# разрешаю подключение к api всем, ограничивать подключения буду во view
'rest_framework.permissions.AllowAny',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
# аутентификацию делаю на уровне сессий (для прямых веб подключений) и с использованием token для фронтэнда
'rest_framework.authentication.SessionAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
'PAGE_SIZE': 1000,
}
- для CORS разрешаю все запросы во время разработки (DEBUG = True, а значит получится и CORS_ORIGIN_ALLOW_ALL = True):
CORS_ORIGIN_ALLOW_ALL = DEBUG
- для djangorestframework-jwt (JSON Web Token) добавляю настройки:
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER': 'back.views.jwt_response_payload_handler',
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
}
- настройки settings.py закончены, сохраняю.
6. Создаю ~/Projects/example.com/back/back/views.py, открываю на редактирование и добавляю функцию:
def jwt_response_payload_handler(token, user=None, request=None):
return {
'access_token': token,
}
Для чего нужна эта функция? Все дело в том, что djangorestframework-jwt, по умолчанию, при запросе ключа возвращает 'token': длинныйдлинныйключ. А ember-simple-auth хочет получить 'access_token': длинныйдлинныйключ , вот поэтому и необходимо сделать эту функцию.
7. В ~/Projects/example.com/back/back/urls.py добавляю api для аутентификации по ключу:
from rest_framework_jwt.views import obtain_jwt_token
#...
urlpatterns = patterns(
'',
# ...
url(r'^api/auth/login/', obtain_jwt_token),
)
8. Делаю миграцию, создаю суперпользователя - admin, запускаю проект back
$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/example.com/back/
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py runserver
- Теперь через браузер проверяю аутентификацию по адресу http://127.0.0.1:8000/api/auth/login/ , после ввода логина и пароля и нажатии на кнопку "POST", должен появиться ключ - "access_token":"длинныйдлинныйключ".
- Не останавливая проект, запускаю новое терминальное окно и проверяю аутентификацию через утилиту командной строки - curl:
$ curl -X POST -d "username=admin&password=парольсуперпользователя" http://127.0.0.1:8000/api/auth/login/
В ответ должен вернуться - {"access_token":"длинныйдлинныйключ"} . Если все так, значит все настроено правильно.
- На этом настройка бакэнда закончена. Приступаю к запуску и настройке фронтэнда.
1. Создаю ember проект - example.com/front
$ cd ~/Projects/example.com
$ sudo npm install -g ember-cli
$ ember new front
2. Запускаю вновь созданный ember проект - front (команда "ember server" или, сокращенно, "ember s")
$ cd ~/Projects/example.com/front
$ ember s
- При запуске вылетает ошибка "Could not start watchman; falling back to NodeWatcher for file system events.", безопасно игнорируем ее как советует https://ember-cli.com/user-guide/#watchman. Хоть я и установил watchman по инструкции - https://facebook.github.io/watchman/docs/install.html, но при запуске команды "ember -v" под пользователем example получаю ошибку, а при запуске от root вышеприведенной ошибки нет. Если знаете как исправить - подскажите.
- смотрю в браузере http://localhost:4200/ - работает
3. Устанавливаю ember-django-adapter адаптер. front (ember) должен понимать как стучаться в back (django)
$ cd ~/Projects/example.com/front
$ ember install ember-django-adapter
- Добавляю в настройки фронтэнда строку - ENV.APP.API_HOST = 'http://localhost:8000';
Редактирую файл настроек Ember проекта: ~/Projects/example.com/front/config/environment.js
if (environment === 'development') {
ENV.APP.API_HOST = 'http://localhost:8000';
...
}
Т.е. при разработке, когда django проект back будет запущен командой "python manage.py runserver", ember проект front будет обращаться к http://localhost:8000/. Наименование api можно изменить допустим на my-api, подробности в документации http://dustinfarris.com/ember-django-adapter/ .
4. Устанавливаю аутентификацию для Ember фронэнда
$ cd ~/Projects/example.com/front
$ ember install ember-simple-auth
5. Создаю фронтэнд приложение - application
- Т.к. в Ember js, по умолчанию, роуты начинаются с приложения application, то и аутентификацию прилеплю на странице application (application хоть и не виден в главном router.js, но при запуске ember проекта сначала обрабатываются именно application). Простыми словами, application - это базовые настройки для Ember js проекта.
Я буду использовать привычный для Django порядок - каждое приложение складывается в отдельную папку, для этого используется в команде "ember generate" с дополнительным ключом "--pod". Команду "ember generate" можно сократить до "ember g".
- Создаю template, controller, adapter для application.
$ cd ~/Projects/example.com/front/
$ ember g route application --pod
$ ember g controller application --pod
$ ember g adapter application --pod
После выполнения этих команд во front/app создалась папка приложения - application и внутри нее файлы route.js, controller.js, adapter.js и template.hbs. Таким образом используя ключ --pod создалась отдельная папка apllication в которой разместились роут, контроллер, адаптер и темплейт. Для меня такая структура более приемлема, потому что в дальнейшем можно быстро копировать приложения в другие проекты.
6. Редактирую темплейт app/application/template.hbs, добавляю:
{{!-- app/application/template.hbs --}}
<div class="menu">
{{#if session.isAuthenticated}}
<a href {{action 'invalidateSession'}}>Выход</a>
{{else}}
{{#link-to 'login'}}Вход{{/link-to}}
{{/if}}
</div>
<div class="main">
{{outlet}}
</div>
Таким образом, для "Выход" навешиваю действие - action 'invalidateSession',а для "Вход" ссылку переход на страницу login - #link-to 'login'. Строка {{outlet}} показывает, что весь вышеприведенный код созданного темплейта application будет наследоваться нижестоящими темплейтами, т.е всеми остальными темплейтами, которые будут созданы в проекте.
7. Редактирую контроллер app/application/controller.js, внедряю в проект сессии и создаю action(действие) - invalidateSession():
// app/application/controller.js
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
actions: {
invalidateSession() {
this.get('session').invalidate();
}
}
});
8. Добавляю аутентификацию в applicaton route
- Сервис сессий имеет события authenticationSucceeded и invalidationSucceeded, которые показывают прошла аутентификация или нет. Чтобы эти события были доступны в сесии на всех страницах сайта добавляю в app/application/route.js:
// app/application/route.js
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin);
9. Добавляю authorizer(авторизатор) в adapter
- после того как аутентификация будет успешно выполнена, для повторного доступа к веб api бакэнда нужен авторизатор. Т.к. адаптер я использую уже готовый - ember-django-adapter, то в application я его расширю указав на авторизатор 'authorizer:oauth2', который создам далее. А пока редактирую app/application/adapter.js :
// app/application/adapter.js
import DRFAdapter from '../adapters/drf';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
export default DRFAdapter.extend(DataAdapterMixin , {
authorizer: 'authorizer:oauth2'
});
10. Создаю аутентификатор и авторизатор oauth2
$ cd ~/Projects/example.com/front/
$ ember g authenticator oauth2
$ ember g authorizer oauth2
- редактирую app/authenticators/oauth2.js (использую стандартную аутентификацию OAuth2PasswordGrant из ember-simple-auth)
// app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';
export default OAuth2PasswordGrant.extend({
serverTokenEndpoint: 'http://127.0.0.1:8000/api/auth/login/',
});
- редактирую app/authorizers/oauth2.js (использую стандартный авторизатор - OAuth2Bearer из ember-simple-auth)
// app/authorizers/oauth2.js
import OAuth2Bearer from 'ember-simple-auth/authorizers/oauth2-bearer';
export default OAuth2Bearer.extend();
11. Приложение login
В app/application/template.hbs я указал использовать для "Вход" переход на login страницу.
- Для приложение login создаю route, controller (template создается автоматом при создании route):
$ cd ~/Projects/example.com/front/
$ ember g route login --pod
$ ember g controller login --pod
При создании роута для login в основном роуте проекта - app/router.js - добавились строки для маршрутизации login приложения:
Router.map(function() {
this.route('login');
});
теперь проект front знает о приложении login.
- Создаю логин форму, редактирую app/login/template.hbs:
{{!-- app/login/template.hbs --}}
<form {{action 'authenticate' on='submit'}}>
<label for="identification">Login</label>
{{input id='identification' placeholder='Enter Login' value=identification}}
<label for="password">Password</label>
{{input id='password' placeholder='Enter Password' type='password' value=password}}
<button type="submit">Вход</button>
{{#if errorMessage}}
<p>{{errorMessage}}</p>
{{/if}}
</form>
У этой формы имеется действие (action) - {{action 'authenticate' on='submit'}} - при нажатии на кнопку "Вход".
- Описываю в login контроллере действие authenticate() при нажатии на кнопку "Вход" (так как при аутентификации используются сессия, то надо и ее объявить через переменную session), редактирую app/login/controller.js:
// app/login/controller.js
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
actions: {
authenticate() {
let { identification, password } = this.getProperties('identification', 'password');
this.get('session').authenticate('authenticator:oauth2', identification, password).
then(() => {
console.log('Success! authenticated with token: ' + this.get('session.data.authenticated.access_token'));
}, (err) => {
alert('Error obtaining token: ' + err.responseText);
}).
catch((reason) => {
this.set('errorMessage', reason.error || reason);
});
}
}
});
При выполнении authenticate() получаем логин и пароль из формы, затем для session выполняем метод authenticate, для которого в качестве аргументов передаем ранее созданный authenticator:oauth2, а также логин и пароль.
- На этом настройка ember js фронтэнда - example.com/front завершена.
Проверяю работу среды разработки DjEmber для example.com
- запускаю бакэнд в 1 терминальном окне
$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/example.com/back/
$ python manage.py runserver
- запускаю фронтэнд во 2 терминальном окне
$ cd ~/Projects/example.com/front/
$ ember s
- запускаю Google Chrome, открываю http://localhost:4200/, запускаю консоль - F12 -> Console.
- нажимаю кнопку вход, ввожу login и password (использую пользователя суперюзер созданного в Django back), нажимаю вход и смотрю в консоль, появилось сообщение:
Success! authenticated with token: длинныйдлинныйключ
DjEmber окружение для разработки готово. Теперь можно создавать api на бакэнде под django-rest-framework и подключаться к нему из ember фронтэнда.
Удачных вам проектов!!!
Права суперпользователя linux нужны только для того, чтобы установить Development Tools и node js, остальные процессы установки делаются под простым пользователем (в этом примере пользователь example).
I. Проект DjEmber - example.com
II. Проект Django - back
III. Проект Ember js - front
I. Проект DjEmber - example.com
- Пользователь - example
- Пользовательская директория /home/example/
- Проект DjEmber - example.com - будет размещаться в /home/example/Projects/example.com/
- Проект Django - back (от слова backend) - будет размещаться в /home/example/Projects/example.com/back/
- Проект Ember - front (от слова frontend) - будет размещаться в /home/example/Projects/example.com/front/
- В Django проекте - back - будет использоваться виртуальное окружение с Python версии 3
- Python 3, установленный из исходников, будет в /home/example/python3/
- Виртуальное окружение для Django проекта - back - /home/example/virtualenv/example.com
- Путь для загруженных программ - /home/example/Downloads/
1. Установка дополнительных программ
$ su -c 'yum groupinstall "Development Tools"'
$ sudo yum install wget
2. Создаю корневой каталог для проекта example.com
$ mkdir -p ~/Projects/example.com
Готовые файлы настроек можно посмотреть и скачать с https://github.com/hairetdin/djember
II. Проект Django - back
1. Установка Python 3 в домашнюю директорию пользователя /home/example/python3
- скачиваю исходники стабильной версии python 3, выбираю в https://www.python.org/downloads/source/
$ cd ~/Downloads/
$ wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz
- распаковываю
$ tar xvf Python-3.5.2.tar.xz
- собираю конфигурацию, указываю путь куда будет установен python3 - /home/example/python3/ и устанавливаю
$ cd Python-3.5.2/
$ $ ./configure --prefix=$HOME/python3
$ make
$ make install
- теперь python3 установлен в /home/example/python3/, проверяю
$ ~/python3/bin/python3 -V
Python 3.5.2
2. Создание виртуального окружения для проекта example.com - back (виртуальные окружения у меня находяться в ~/virtualenv)
$ cd ~
$ mkdir -p virtualenv
$ ~/python3/bin/pyvenv ~/virtualenv/example.com
- проверяю работу созданного виртуального окружения - virtualenv/example.com
$ source ~/virtualenv/example.com/bin/activate
в терминале должна появиться строка начинающаяся с - (example.com). Теперь запущу python и посмотрю версию
$ python -V
Python 3.5.2
- деактивация виртуального окружения:
$ deactivate
3. Установка python приложений в виртуальное окружение virtualenv/example.com
- Активирую виртуальное окружение и устанавливаю python приложения
$ source ~/virtualenv/example.com/bin/activate
$ pip install django
$ pip install djangorestframework
$ pip install djangorestframework-jwt
$ pip install django-filter
$ pip install django-cors-headers
Если не будете использовать django-filter, то ставить необязательно.
4. Создаю Django бакэнд проект для example.com
Виртуальное окружение virtualenv/example.com дожно быть активировано.
- перехожу в корень проекта example.com
$ cd ~/Projects/example.com/
- создаю проект back
$ django-admin startproject back
- проверяю созданные Django проект
$ cd ~/Projects/example.com/back/
$ python manage.py runserver
Смотрю в браузере http://127.0.0.1:8000/ - работает, показывает страницу приветствия - "Congratulations on your first Django-powered page."
Хорошо, останавливаю запущенный back проект - Ctrl+C
5. Делаю настройки для ранее установленных python приложений в ~/Projects/example.com/back/back/settings.py
Я для этого я использую редактор Atom, открываю на редактирование settings.py и вношу следующие изменения:
- в INSTALLED_APPS добавляю 'rest_framework' и 'corsheaders'
INSTALLED_APPS = (
...
# external apps
'rest_framework',
'corsheaders',
)
- в MIDDLEWARE_CLASSES добавляю 'corsheaders.middleware.CorsMiddleware',
MIDDLEWARE_CLASSES = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
- добавляю новую конфигурацию для REST_FRAMEWORK
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
# разрешаю подключение к api всем, ограничивать подключения буду во view
'rest_framework.permissions.AllowAny',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
# аутентификацию делаю на уровне сессий (для прямых веб подключений) и с использованием token для фронтэнда
'rest_framework.authentication.SessionAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
'PAGE_SIZE': 1000,
}
- для CORS разрешаю все запросы во время разработки (DEBUG = True, а значит получится и CORS_ORIGIN_ALLOW_ALL = True):
CORS_ORIGIN_ALLOW_ALL = DEBUG
- для djangorestframework-jwt (JSON Web Token) добавляю настройки:
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER': 'back.views.jwt_response_payload_handler',
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
}
- настройки settings.py закончены, сохраняю.
6. Создаю ~/Projects/example.com/back/back/views.py, открываю на редактирование и добавляю функцию:
def jwt_response_payload_handler(token, user=None, request=None):
return {
'access_token': token,
}
Для чего нужна эта функция? Все дело в том, что djangorestframework-jwt, по умолчанию, при запросе ключа возвращает 'token': длинныйдлинныйключ. А ember-simple-auth хочет получить 'access_token': длинныйдлинныйключ , вот поэтому и необходимо сделать эту функцию.
7. В ~/Projects/example.com/back/back/urls.py добавляю api для аутентификации по ключу:
from rest_framework_jwt.views import obtain_jwt_token
#...
urlpatterns = patterns(
'',
# ...
url(r'^api/auth/login/', obtain_jwt_token),
)
8. Делаю миграцию, создаю суперпользователя - admin, запускаю проект back
$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/example.com/back/
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py runserver
- Теперь через браузер проверяю аутентификацию по адресу http://127.0.0.1:8000/api/auth/login/ , после ввода логина и пароля и нажатии на кнопку "POST", должен появиться ключ - "access_token":"длинныйдлинныйключ".
- Не останавливая проект, запускаю новое терминальное окно и проверяю аутентификацию через утилиту командной строки - curl:
$ curl -X POST -d "username=admin&password=парольсуперпользователя" http://127.0.0.1:8000/api/auth/login/
В ответ должен вернуться - {"access_token":"длинныйдлинныйключ"} . Если все так, значит все настроено правильно.
- На этом настройка бакэнда закончена. Приступаю к запуску и настройке фронтэнда.
III. Проект Ember js - front
1. Создаю ember проект - example.com/front
$ cd ~/Projects/example.com
$ sudo npm install -g ember-cli
$ ember new front
2. Запускаю вновь созданный ember проект - front (команда "ember server" или, сокращенно, "ember s")
$ cd ~/Projects/example.com/front
$ ember s
- При запуске вылетает ошибка "Could not start watchman; falling back to NodeWatcher for file system events.", безопасно игнорируем ее как советует https://ember-cli.com/user-guide/#watchman. Хоть я и установил watchman по инструкции - https://facebook.github.io/watchman/docs/install.html, но при запуске команды "ember -v" под пользователем example получаю ошибку, а при запуске от root вышеприведенной ошибки нет. Если знаете как исправить - подскажите.
- смотрю в браузере http://localhost:4200/ - работает
3. Устанавливаю ember-django-adapter адаптер. front (ember) должен понимать как стучаться в back (django)
$ cd ~/Projects/example.com/front
$ ember install ember-django-adapter
- Добавляю в настройки фронтэнда строку - ENV.APP.API_HOST = 'http://localhost:8000';
Редактирую файл настроек Ember проекта: ~/Projects/example.com/front/config/environment.js
if (environment === 'development') {
ENV.APP.API_HOST = 'http://localhost:8000';
...
}
Т.е. при разработке, когда django проект back будет запущен командой "python manage.py runserver", ember проект front будет обращаться к http://localhost:8000/. Наименование api можно изменить допустим на my-api, подробности в документации http://dustinfarris.com/ember-django-adapter/ .
4. Устанавливаю аутентификацию для Ember фронэнда
$ cd ~/Projects/example.com/front
$ ember install ember-simple-auth
5. Создаю фронтэнд приложение - application
- Т.к. в Ember js, по умолчанию, роуты начинаются с приложения application, то и аутентификацию прилеплю на странице application (application хоть и не виден в главном router.js, но при запуске ember проекта сначала обрабатываются именно application). Простыми словами, application - это базовые настройки для Ember js проекта.
Я буду использовать привычный для Django порядок - каждое приложение складывается в отдельную папку, для этого используется в команде "ember generate" с дополнительным ключом "--pod". Команду "ember generate" можно сократить до "ember g".
- Создаю template, controller, adapter для application.
$ cd ~/Projects/example.com/front/
$ ember g route application --pod
$ ember g controller application --pod
$ ember g adapter application --pod
После выполнения этих команд во front/app создалась папка приложения - application и внутри нее файлы route.js, controller.js, adapter.js и template.hbs. Таким образом используя ключ --pod создалась отдельная папка apllication в которой разместились роут, контроллер, адаптер и темплейт. Для меня такая структура более приемлема, потому что в дальнейшем можно быстро копировать приложения в другие проекты.
6. Редактирую темплейт app/application/template.hbs, добавляю:
{{!-- app/application/template.hbs --}}
<div class="menu">
{{#if session.isAuthenticated}}
<a href {{action 'invalidateSession'}}>Выход</a>
{{else}}
{{#link-to 'login'}}Вход{{/link-to}}
{{/if}}
</div>
<div class="main">
{{outlet}}
</div>
Таким образом, для "Выход" навешиваю действие - action 'invalidateSession',а для "Вход" ссылку переход на страницу login - #link-to 'login'. Строка {{outlet}} показывает, что весь вышеприведенный код созданного темплейта application будет наследоваться нижестоящими темплейтами, т.е всеми остальными темплейтами, которые будут созданы в проекте.
7. Редактирую контроллер app/application/controller.js, внедряю в проект сессии и создаю action(действие) - invalidateSession():
// app/application/controller.js
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
actions: {
invalidateSession() {
this.get('session').invalidate();
}
}
});
8. Добавляю аутентификацию в applicaton route
- Сервис сессий имеет события authenticationSucceeded и invalidationSucceeded, которые показывают прошла аутентификация или нет. Чтобы эти события были доступны в сесии на всех страницах сайта добавляю в app/application/route.js:
// app/application/route.js
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin);
9. Добавляю authorizer(авторизатор) в adapter
- после того как аутентификация будет успешно выполнена, для повторного доступа к веб api бакэнда нужен авторизатор. Т.к. адаптер я использую уже готовый - ember-django-adapter, то в application я его расширю указав на авторизатор 'authorizer:oauth2', который создам далее. А пока редактирую app/application/adapter.js :
// app/application/adapter.js
import DRFAdapter from '../adapters/drf';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
export default DRFAdapter.extend(DataAdapterMixin , {
authorizer: 'authorizer:oauth2'
});
10. Создаю аутентификатор и авторизатор oauth2
$ cd ~/Projects/example.com/front/
$ ember g authenticator oauth2
$ ember g authorizer oauth2
- редактирую app/authenticators/oauth2.js (использую стандартную аутентификацию OAuth2PasswordGrant из ember-simple-auth)
// app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';
export default OAuth2PasswordGrant.extend({
serverTokenEndpoint: 'http://127.0.0.1:8000/api/auth/login/',
});
- редактирую app/authorizers/oauth2.js (использую стандартный авторизатор - OAuth2Bearer из ember-simple-auth)
// app/authorizers/oauth2.js
import OAuth2Bearer from 'ember-simple-auth/authorizers/oauth2-bearer';
export default OAuth2Bearer.extend();
11. Приложение login
В app/application/template.hbs я указал использовать для "Вход" переход на login страницу.
- Для приложение login создаю route, controller (template создается автоматом при создании route):
$ cd ~/Projects/example.com/front/
$ ember g route login --pod
$ ember g controller login --pod
При создании роута для login в основном роуте проекта - app/router.js - добавились строки для маршрутизации login приложения:
Router.map(function() {
this.route('login');
});
теперь проект front знает о приложении login.
- Создаю логин форму, редактирую app/login/template.hbs:
{{!-- app/login/template.hbs --}}
<form {{action 'authenticate' on='submit'}}>
<label for="identification">Login</label>
{{input id='identification' placeholder='Enter Login' value=identification}}
<label for="password">Password</label>
{{input id='password' placeholder='Enter Password' type='password' value=password}}
<button type="submit">Вход</button>
{{#if errorMessage}}
<p>{{errorMessage}}</p>
{{/if}}
</form>
У этой формы имеется действие (action) - {{action 'authenticate' on='submit'}} - при нажатии на кнопку "Вход".
- Описываю в login контроллере действие authenticate() при нажатии на кнопку "Вход" (так как при аутентификации используются сессия, то надо и ее объявить через переменную session), редактирую app/login/controller.js:
// app/login/controller.js
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
actions: {
authenticate() {
let { identification, password } = this.getProperties('identification', 'password');
this.get('session').authenticate('authenticator:oauth2', identification, password).
then(() => {
console.log('Success! authenticated with token: ' + this.get('session.data.authenticated.access_token'));
}, (err) => {
alert('Error obtaining token: ' + err.responseText);
}).
catch((reason) => {
this.set('errorMessage', reason.error || reason);
});
}
}
});
При выполнении authenticate() получаем логин и пароль из формы, затем для session выполняем метод authenticate, для которого в качестве аргументов передаем ранее созданный authenticator:oauth2, а также логин и пароль.
- На этом настройка ember js фронтэнда - example.com/front завершена.
Проверяю работу среды разработки DjEmber для example.com
- запускаю бакэнд в 1 терминальном окне
$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/example.com/back/
$ python manage.py runserver
- запускаю фронтэнд во 2 терминальном окне
$ cd ~/Projects/example.com/front/
$ ember s
- запускаю Google Chrome, открываю http://localhost:4200/, запускаю консоль - F12 -> Console.
- нажимаю кнопку вход, ввожу login и password (использую пользователя суперюзер созданного в Django back), нажимаю вход и смотрю в консоль, появилось сообщение:
Success! authenticated with token: длинныйдлинныйключ
DjEmber окружение для разработки готово. Теперь можно создавать api на бакэнде под django-rest-framework и подключаться к нему из ember фронтэнда.
Удачных вам проектов!!!