Игор — инженер-программист в BOL.COM, энтузиаст функционального программирования и любитель кофе.

В этом руководстве вы узнаете, как настроить простой проект Phoenix API и защитить его конечные точки, используя POW в качестве диспетчера аутентификации и Joken в качестве диспетчера токенов JWT без сохранения состояния.

Используемые технологии

  • Эликсир 1.10.2
  • Феникс 1.5.1
  • Шестнадцатеричный
  • Экто 3.4
  • Поддержка 1.0.19
  • Джокен 2.0
  • ПостгресSQL
  • Докер

Начиная

Прежде всего, нам нужно подготовить нашу среду Erlang и Elixir, для этого я буду использовать asdf-vm, поэтому обязательно установите и настройте его, прежде чем следовать этому руководству.

Во-первых, нам нужно установить плагины Erlang и Elixir для ASDF, для этого вы должны выполнить следующие команды:

$ asdf plug add erlang
$ asdf plug add elixir

Затем вы можете установить Erlang 22.3 и Elixir 1.10.2.

$ asdf install erlang 22.3
$ asdf install elixir 1.12.2

После установки вы можете установить управляемые инструменты asdf в качестве глобальных инструментов.

$ asdf global erlang 22.3
$ asdf global elixir 1.12.2

Теперь вы можете проверить текущий установленный инструментарий

$ elixir --version
Erlang/OTP 22 [erts-10.7] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe]
Elixir 1.10.2 (compiled with Erlang/OTP 21)

Хороший! Вы подготовили среду, чтобы установить зависимости и управлять сборкой приложения, я буду использовать hex, вы можете установить его, запустив:

$ mix local.hex

Создание вашего приложения Phoenix

Phoenix — самый известный фреймворк для Elixir, с его помощью вы можете создавать веб-приложения, API и многое другое. Для этого урока я создам простой проект, просто чтобы обслуживать API.

Сначала нам нужно установить генератор феникса.

$ mix archive.install hex phx_new 1.5.1

Затем мы можем загрузить наше приложение

$ mix phx.new --no-html --no-webpack powjwt

И вуаля, это оставит нас с нашим базовым проектом, теперь нам просто нужно настроить нашу базу данных. Для этого мы будем использовать Postgres в док-контейнере.

$ docker pull postgres
$ docker run --name powjwt-postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres

Теперь вам нужно запустить миграцию по умолчанию

$ mix ecto.setup

Сделанный! Вы можете проверить, все ли в порядке.

$ mix phx.server
[info] Running PowjwtWeb.Endpoint with cowboy 2.7.0 at 0.0.0.0:4000 (http)
[info] Access PowjwtWeb.Endpoint at http://localhost:4000

Вы можете получить доступ к http://localhost:4000/dashboard, и вы увидите что-то вроде этого:

Настройка аутентификации

Теперь нам просто нужно собрать наши модули аутентификации, для этого мы будем использовать 2 сторонние библиотеки, POW и Joken.

Сначала откройте файл mix.exs и добавьте две зависимости.

{:pow, "~> 1.0"},
{:joken, "~> 2.2"},

Теперь загрузите зависимости

$ mix deps.get

Настройка POW

POW — это комплексное решение для создания потоков аутентификации и авторизации, давайте настроим его!

$ mix pow.install

конфиг/config.exs

lib/powjwt_web/endpoint.ex

lib/powjwt_web/router.ex

Хороший! Но как войти? Что ж, POW предоставляет шаблон входа по умолчанию, но он не подходит для аутентификации API без сохранения состояния, поэтому мы создадим свой собственный!

Во-первых, давайте создадим нашу структуру объекта входа в систему.

lib/powauth/auth/user_registration.exs

Теперь давайте создадим наш контроллер регистрации

lib/powauth_web/controllers/user_registration.ex

Ладно… но как это работает? Что ж, POW предоставляет подключаемый модуль, который позволяет вам реализовать собственный поток аутентификации, в нашем случае мы хотим создать аутентификацию jwt без сохранения состояния, поэтому сначала нам нужно создать наш менеджер токенов, и для этого мы будем использовать Joken, давайте создадим его.

lib/config/dev.exs

# Joken
config :joken, default_signer: "secret"

lib/powauth/auth/token.ex

lib/powauth/auth/auth_flow.ex

Разобьём на части:

  1. Функция fetch вызывается каждый раз, когда выполняется вызов API, мы будем использовать ее для извлечения токена из заголовка авторизации и для проверки токена, если токен есть и он действителен, мы возвращаем токен и добавляем его и user_id к свойствам соединения.
  2. Функция создания вызывается, когда пользователь запрашивает создание токена, она создает и подписывает токен JWT, используя конфигурации, определенные в структуре Token.
  3. Мы не будем реализовывать поток удаления здесь, но если вы хотите, вы можете создать механизм для аннулирования токенов JWT, я оставлю это вам.

Понятно? Здорово! Теперь давайте добавим поток регистрации на наш маршрутизатор, для этого нам нужно включить плагин AuthFlow для конвейера API и создать конечную точку регистрации.

lib/powauth_web/router.ex

Ну, раз уж мы здесь! Давайте также реализуем поток входа в систему

lib/powjwt/auth/user_pass_login.ex

lib/powjwt_web/controllers/user_login.ex

lib/powauth_web/router.ex

Хороший! Проверим регистрацию

$ mix ecto.migrate
$ mix phx.server

Опубликовать создание пользователя на http://localhost:4000/api/auth/register

И тада! Вот ваш токен авторизации! Хорошо, но как мне защитить свои точки входа? Давайте создадим тестовую точку входа для этого.

Сначала давайте создадим обработчик ошибок авторизации

lib/powjwt_web/controllers/auth_errorhandler.ex

Давайте создадим простой контроллер, который будет возвращать токен, вошедший в систему, и user_id.

lib/powjwt_web/controller/home.ex

lib/powjwt_web/router.ex

Давай попробуем!

  1. Без токена

2. С токеном

Тада! Работает как шарм.

Полный код можно посмотреть на Github

Спасибо за внимание, и я надеюсь, что это руководство поможет! До следующего раза!