Авторизация это проверка того, какие действия пользователь может выполнять, и к каким ресурсам он имеет доступ. В отличие от аутентификации, которая просто подтверждает, что пользователь является тем, за кого себя выдает, авторизация отвечает на вопрос: "Что пользователь может делать?".
Обычно авторизация реализуется на стороне сервера. Когда пользователь отправляет запрос на выполнение какой-либо операции или доступ к ресурсу, сервер проверяет, имеет ли он право на это. Эта проверка может включать взаимодействие с базой данных или специальным сервисом, который хранит информацию о правах доступа пользователя.
Представьте себе веб-приложение для управления проектами. Допустим, что в системе есть два типа пользователей: администраторы и обычные пользователи. Администратор может создавать, редактировать и удалять проекты, тогда как обычный пользователь может только просматривать и комментировать их. Когда пользователь пытается удалить проект, сервер должен проверить, является ли он администратором. Эта проверка и есть процесс авторизации.
В распределенных системах, где множество сервисов взаимодействуют друг с другом, авторизация может стать сложной задачей по нескольким причинам:
- Высокая нагрузка на серверы: Каждое обращение требует запроса на сервер для проверки прав доступа, что может привести к повышенной нагрузке и задержкам.
- Узкое место системы: Если сервер авторизации становится недоступным, вся система может перестать работать.
- Задержки из-за сетевого взаимодействия: Взаимодействие между различными компонентами системы, особенно в микросервисной архитектуре, может приводить к задержкам из-за сетевых вызовов.
Чтобы преодолеть эти сложности, авторизационные данные можно перенести на сторону клиента, передав их ему после успешной аутентификации. Клиент же, обращаясь к ресурсам внутри системы, будет передавать эти данные на каждый запрос, помогая сервисам определить, имеет ли он права на такой запрос. Главная проблема в такой схеме, как обеспечить невозможность подмены данных клиентов? Ведь если передавать их в открытом виде, то клиент сможет изменить значения и, например, стать администратором с полным набором прав.
JWT
Для решения этой задачи подходит JSON Web Tokens (JWT). JWT — это компактный, URL-безопасный формат для передачи данных между сторонами в виде JSON-объекта, который включает в себя полезную нагрузку (payload), подписанную или зашифрованную для обеспечения безопасности.
При использовании JWT права доступа пользователя могут быть закодированы внутрь токена, который затем передается клиенту. Этот токен включает в себя всю необходимую информацию для авторизации, и сервисы могут проверять его подлинность и содержание без необходимости обращаться к базе данных или серверу авторизации. Это дает ряд преимуществ:
- Автономность: Сервисы могут проверять права пользователя без необходимости отправлять дополнительные запросы на сервер.
- Снижение нагрузки: Снижается нагрузка на центральный сервер авторизации, так как проверка прав может происходить локально на стороне сервиса.
JWT активно используются в системах единой авторизации SSO. Это подход, при котором для доступа ко всем сервисам системы достаточно авторизоваться ровно один раз, в специально предназначенном для этого сервисе.
curl -X POST https://http.hexlet.app/http-api/login \
-H "Content-Type: application/json" \
-d '{"email": "max@hotmail.com","password": "password"}'
Работает это так. Пользователь проходит аутентификацию один раз, после чего ему выдается JWT, содержащий информацию о его правах доступа. Этот токен передается между различными сервисами, и каждый сервис может локально проверять его подлинность и права пользователя без необходимости обращаться к центральному серверу.
В большинстве случаев для передачи токена используется, уже знакомый нам, Bearer механизм, где токен передается в заголовке:
Authorization: Bearer <token>
Пример запроса с заголовком:
curl -X POST https://http.hexlet.app/http-api/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer r4AR4Fo0j29s9mFk4IUVA2rGTQmIrHWlioifaJLSQQYHbTXHxtSLFUVp8PANrRoAb7fgkSsbN7lt4a86pcJ07ivUpxBLyyCHaY4Pp9I7hRPphCHM7xpZ1om1" \
-d '{"firstName": "SomeName", "lastName": "SomeLastName", "email": "home@hotmail.com", "password": "somePassword"}'
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.