С некоторым волнением и страхом я подошел к финальному проекту. «Предполагается, что это станет вашим величайшим произведением — кульминацией
всех навыков, которым вы научились до сих пор», — сказали они. «С ума сойти!… Вы можете добавлять столько вещей, сколько хотите», — сказали они.

Последнее одобрение было приглашением к слишком большому веселью с частыми переосмыслениями того, как масштабировать следующее препятствие кодирования. Вот что я в итоге построил:

Snappy Name: We/Mix

Домен: полный CRUD инструмент для создания плейлистов музыкальных видео.

Почему? Потому что музыка стимулирует творчество и это весело.

Исходный API: Audiodb.com и iFrame Player API YouTube, используемые через пакет react-youtube.

Аутентификация: bcrypt gem и веб-токены JSON (алгоритм HS256)

Тестирование Rails API: тестирование моделей и запросов через rspec-rails, shoulda-matchers, factory_bot_rails и Faker.

Пакеты стилей: fixed-data-table-2, react-image-fallback, semantic-ui-react

Я так многому научился, работая над этим проектом, который включает в себя не только один пост в блоге. Для начала мне нужно было применить на практике разработку через тестирование и аутентификацию веб-токенов JSON. Ниже приведены некоторые основные моменты:

Создание полезного API Rails

Хотя я проработал лабораторные работы и понял концепции в их отдельных частях, я еще не создал API, который мог бы обрабатывать действия CRUD. Казалось, что лучший способ добиться этого — использовать подход Test Driven Development, чтобы гарантировать, что я создам то, что хочу.

Я опирался на серию видеороликов для инструкторов Люка в качестве руководства по созданию тестов и обеспечению того, чтобы мой API работал так, как ожидалось. Я получил много практики, используя Postman, использовал его лишь изредка в лабораториях по разработке API, и, наконец, стал действительно комфортно его использовать. Я также познакомился с RESTed, еще одним отличным инструментом для быстрого форматирования и отправки HTTP-запросов и просмотра ответа.

Аутентификация

Мне было любопытно использовать веб-токены JSON, поскольку они не были представлены в материалах курса. Следуя одному из вышеупомянутых видеороликов учебной группы Люка по первоначальной сборке серверной части, я погрузился в «Дикий Запад» аутентификации React, чтобы найти собственное решение. Вот краткое изложение шагов, которые я предпринял для создания своего:

Бэкенд Rails: мы-смешиваем-api (1)

Шаг 1. Внедрите хэширование и шифрование паролей с помощью bcrypt

  1. Включил bcrypt gem в моем gemfile для хеширования и шифрования паролей и запустил bundle install
  2. Создал миграцию пользователя с атрибутами :username, :password_digest и :email
  3. Переход к пользовательской модели позволил has_secure_password использовать преимущества методов ActiveRecord, которые подключаются к bcrypt (например, authenticate ). Также добавлены проверки наличия и уникальности :email и :username.
  4. Теперь маршруты необходимы для возможности создания пользователей при регистрации. В файле config/routes.rb я добавил `post ‘/signup’ к: маршруту «users#signup»`
  5. В Users Controller, users_controller.rb, я создал метод регистрации и закрытый `user_params`, чтобы убедиться, что только разрешенные параметры включены в создание пользователя.
  6. Я добавил Контроллер сеансов, а затем написал действие basiclogin.^
  7. Когда контроллеры пользователей и сеансов настроены на шифрование паролей и последующую аутентификацию пользователей, я приступил к реализации JWT.

Шаг 2. Включите кодирование и декодирование пользовательских атрибутов с помощью веб-токенов JSON

  1. Добавил jwt-gem в мой gemfile (информация JWT: https://jwt.io/) и запустил bundle install
  2. Выберите алгоритм хеширования — я использовал по умолчанию HMAC (HS256).
  3. Мне нужны были методы для создания и декодирования JWT. Чтобы реализовать это, я создал auth.rb файл в папке lib, построил класс Auth, а затем построил методы классов create_token и decode_token согласно видео. Метод create_token принимает объект User в качестве аргумента, а затем создает связанный с ним токен.
  4. Теперь, чтобы сделать эти методы полезными. В контроллере пользователей я хочу создать токен, когда пользователь подписывается на мое приложение. Если пользователь сохранился, то одновременно будет создан токен, что фактически позволит им войти в систему в одно и то же время.
  5. Что касается контроллера сеансов и создания сеанса, действие login получает адрес электронной почты и пароль пользователя, а затем находит пользователя по электронной почте и аутентифицирует его пароль. Если оба значения верны, токен JWT создается и отправляется клиенту через JSON.

^Если присутствует, закомментируйте protect_from_forgery_with: :exception строку в `application_controller.rb`. protect_from_forgery существует для защиты приложений Rails от подделки межсайтовых запросов (CSRF), серьезной уязвимости, связанной с доверием к файлам cookie идентификации сеанса, передаваемым между браузером и сервером. Веб-токены JSON заменят функцию защиты CSRF по умолчанию в Rails.

Клиент React/Redux: мы микшируем приложение

Что касается React, моей целью было дать пользователям возможность

  • Войти и CRUD свой собственный плейлист видео
  • Запретить другим пользователям просматривать их плейлист или выполнять любые другие действия с учетной записью Пользователя.
  • Выйти

Для этого я сделал следующее:

  1. Созданы контейнеры LoginPage и SignUpPage.
  2. Я решил, что JWT будет храниться в localStorage, который сам по себе не связан с хранилищем. По этой причине я решил поместить функции, участвующие в вызовах Login и Signup We/Mix API, в каталог API. Регистрация или регистрация пользователя происходит в классе UserApi, содержащем функцию регистрации, которая отправляет адрес электронной почты, имя пользователя и пароль нового пользователя в действие create в Users Controller. Вход пользователя происходит в SessionApi Class, содержащем функцию входа, которая отправляет учетные данные пользователя в действие login в контроллере сеансов. Оба этих вызова приводят к возвращаемому JWT, который затем сохраняется в файле localStorage окна.
  3. Я по-прежнему хотел, чтобы действия сеанса и пользователя были связаны с магазином. я сделал это по

(1) импорт bindActionCreators из redux и connect из react-redux в контейнеры LoginPage и SignUpPage.

(2) настройка файла sessionActions для хранения создателей действий, связанных с сеансами. Пока что эти создатели действий устанавливают полученный JWT в localStorage и удаляют токен из localStorage при выходе из системы.

(3) Аналогичным образом я настроил файл userActions для хранения создателей действий, связанных с пользователем, которые устанавливают для полученного JWT значение localStorage.

(4)Я все еще обдумываю возможность добавить действия в каждый из этих файлов и отправить их в user_reducer для добавления атрибут «аутентифицированный» для магазина. Однако пока не ясно, будет ли это полезно, так как я успешно реализовал компонент-оболочку EnsureLoggedIn, что приводит меня к…

4. Защита от других зрителей: API Rails отправляет только видео, связанные с авторизованным пользователем в действии index. Я создал компонент-оболочку EnsureLoggedIn для защиты маршрутов, если пользователь не вошел в систему.

Благодарности

Со всеми идеями в моей голове я не смог бы добиться этого без сообщества Learn и обсуждения идей с друзьями и инструкторами. Особая благодарность Люку Генко за руководство, Элис Бальбуэна за неоценимую учебную группу и уделенное время, а также Крису Коулу, Дэвиду Кеннеллу и Джейси Хейден за их общую поддержку. Спасибо!!

использованная литература

  1. Люк Генко, Аутентификация JWT с помощью Rails, 27 января 2017 г.
  2. Софи ДеБенедетто, Аутентификация JWT с помощью React + Redux, 9 сентября 2016 г.
  3. Адам Хури, «JavaScript Storage Interface sessionStorage localStorage Tutorial,» 4 октября 2015 г.
  4. Раджа Рао Д.В., «React Redux CRUD App/react-redux-blog, по состоянию на ноябрь 2017 г. (Связанный блог: Защита приложений React Redux с помощью токенов JWT)
  5. Скотт Луптовски, Добавление разделов входа и аутентификации в приложение React или React Native, 25 августа 2016 г.