Глубокое погружение в Strapi для создания системы запросов функций EOS в GSOC’20
Hola a todos! Дайте мне компанию, пока я объясню вам внутренности Strapi и то, как я использую различные механизмы для реализации индивидуальных и безопасных решений для нашей системы запросов функций. Возьмите свой напиток, сядьте поудобнее и расслабьтесь, пока я расскажу вам о деталях.
Что я делал на этой неделе?
Strapi - это волшебство, лежащее в основе наших замечательных приложений в EOS. Это ведущая CMS с открытым исходным кодом. Это 100% Javascript, полностью настраиваемый и ориентированный на разработчиков.
На этой неделе я завершил аутентификацию пользователя и авторизацию в нашей системе. Сюда входят функции регистрации, входа, выхода, забытого пароля и сброса пароля. Давайте посмотрим, как это сделать с помощью Strapi и React.
Strapi предоставляет систему плагинов, в которой каждый плагин похож на небольшое независимое приложение. У него есть собственная бизнес-логика с выделенными моделями, контроллерами, сервисами, промежуточным программным обеспечением или хуками. Он также может иметь собственный пользовательский интерфейс, интегрированный в панель администратора.
Я использовал плагин Roles and Permissions для выполнения своих задач недели. Этот плагин обеспечивает способ защиты нашего API с помощью полного процесса аутентификации на основе JWT
. Каждый раз при отправке запроса API сервер проверяет наличие заголовка Authorization
и проверяет, имеет ли пользователь, отправляющий запрос, доступ к ресурсу. Для этого наш JWT
содержит наш идентификатор пользователя, и мы можем сопоставить группу, в которой находится наш пользователь, и в конце узнать, разрешает ли группа доступ к маршруту.
Ответ API на маршрут аутентификации содержит JWT
пользователя в jwt
ключе. Нам нужно будет сохранить это JWT
в нашем приложении, это важно, потому что вам придется использовать его при следующих запросах.
Мы решили сохранить JWT
в httpOnly
cookie вместо простого решения - хранить его в localStorage
, что делает наше приложение уязвимым для XSS-атак. Это означает, что нам нужно настроить Strapi для установки jwt
в cookie вместо того, чтобы возвращать его в ответе API. Это гарантирует, что нашему клиентскому приложению не нужно хранить конфиденциальные данные для будущих аутентифицированных запросов.
Strapi внутренне использует Koa.js
, новую веб-платформу, разработанную командой Express, которая стремится стать более компактной, более выразительной и надежной основой для веб-приложений и API. Я быстро изучил базовый синтаксис, так как уже знаком с Node.js
и Express
.
Теперь каждый плагин в Strapi следует архитектуре, приведенной ниже, и все установленные плагины можно найти в папке node_modules
с соглашением об именах strapi-plugin-*
.
plugin/
└─── admin/ # Contains the plugin's front-end
| └─── src/ # Source code directory
| └─── index.js # Entry point of the plugin
| └─── pluginId.js # Name of the plugin
| └─── lifecycles.js # File in which the plugin sets the | hooks to be ran in another plugin.
| └─── components/ # Contains the list of React components | used by the plugin
| └─── containers/
| └─── App/ # Container used by every others containers
| └─── Initializer/ # This container is required, it is | used to executed logic right after the plugin is mounted.
| └─── translations/ # Contains the translations to make | the plugin internationalized
| └─── en.json
| └─── index.js # File that exports all the plugin's translations.
| └─── fr.json
└─── config/ # Contains the configurations of the plugin
| └─── functions/
| └─── bootstrap.js # Asynchronous bootstrap function that
| runs before the app gets started
| └─── policies/ # Folder containing the plugin's policies
| └─── queries/ # Folder containing the plugin's models queries
| └─── routes.json # Contains the plugin's API routes
└─── controllers/ # Contains the plugin's API controllers
└─── middlewares/ # Contains the plugin's middlewares
└─── models/ # Contains the plugin's API models
└─── services/ # Contains the plugin's API services
Чтобы настроить эти установленные плагины, мы можем работать в каталоге /extensions
. Он содержит все настраиваемые файлы плагинов. Я настроил плагин user-permissions
, изменив файл контроллера Auth.js
для выдачи JWT
пользователю и установив его в httpOnly
cookie после того, как будут выполнены все проверки на стороне сервера. Я также изменил ответ контроллера, чтобы он возвращал «статусный» ключ со значением «Authenticated» вместо токена. Это подтверждает, что пользователь прошел аутентификацию.
Ждать! Strapi считывает токен из заголовка Authorization
в запросе API, поэтому пока это не сработает. Далее я добавил файл permissions.js
в папку policies
, где я прикрепляю токен к заголовку после прочтения его из файла cookie, который был установлен ранее.
Политики в Strapi - это функции, которые могут выполнять определенную логику для каждого запроса, прежде чем он достигнет действия контроллера. В основном они используются для простой защиты бизнес-логики. Каждый маршрут проекта можно связать с массивом политик.
Теперь, чтобы реализовать функцию выхода из системы, я настроил пользовательский маршрут /logout
с контроллером, чтобы установить для токена значение null в файле cookie. Это безопасно уничтожает сеанс пользователя за секунды.
Ребята, терпения! Наш пользователь тоже может забыть свой пароль. Я использовал службу sendgrid
для отправки пользователям электронной почты со ссылкой, которая содержит параметр URL code
, который требуется для сброса пароля пользователя.
Я реализовал функциональность на стороне клиента, включая запросы к API, в настраиваемом хуке React с именем useAuth
, чтобы наконец завершить гибкую задачу.
Что будет дальше?
На этой неделе я реализую функцию для создания нового запроса, а также для чтения и отображения существующих запросов функций вместе со всеми атрибутами, такими как голоса и комментарии, в привлекательном пользовательском интерфейсе.
Я также попытаюсь настроить поставщиков, которые в настоящее время не работают из-за проблемы в Strapi v3.0.1 здесь.
Я где-нибудь застрял?
Мы все обязательно упадем. Все великие дела не начинаются безупречно. Сначала я не мог понять, как правильно управлять состоянием пользователя, и попытался использовать reducer
, но при обновлении страницы состояние сбрасывалось до исходного. Наконец, я реализовал идею чтения состояния из localStorage
без сохранения какой-либо конфиденциальной информации.
Strapi по умолчанию использует службу sendmail
для отправки писем пользователям, но она не работала и всегда возвращала код состояния 400
. Я добавил службу sendgrid
, чтобы решить эту проблему.
Вся эта суета и суета ознаменовали конец моей недели завораживающим кольцевым солнечным затмением 21 июня 2020 года. Следите за обновлениями, поскольку в ближайшие недели мы представим некоторые удивительные особенности.