@kirill-93

Как называется такая аутентификация и как выбрать правильный способ?

Прочел несколько статей по способам аутентификации. В голове немного каша и осталось несколько вопросов.
Сессии.
Сессия - это способ сохранения состояния на сервере между запросами пользователя. На сервере создается сессия (обычно это файл или запись в БД или в памяти). Это сессия имеет id, который возвращается пользователю на клиент и сохраняется в куках. При дальнейших обращениях к серверу, клиент передает куку и сервер знает, кто к нему обращается.
В сессию можно добавлять или удалять данные. Сессию также можно удалить на сервере и таким образом разлогинить пользователя.
К минусам данной реализации относят какие-то проблемы с куками в мобильных приложениях. Какие именно проблемы не пишут. Еще сессии по умолчанию создаются на каждого нового клиента. То есть при каждом посещении сайта, создается файл на жестком диске.

Токены.
Например, JWT. На сервере специальная библиотека шифрует данные о пользователе и получает токен. Полученный токен отправляется пользователю и сохраняется где-нибудь, обычно в localStorage. При дальнейших обращениях к серверу, пользователь отправляет этот токен на сервер, где он расшифровывается. Тут отличие от сессии в том, что данные в существующем токене добавлять/удалять нельзя, нужно выпускать новый токен.
Минусы у такого подхода следующие:
1) Невозможно инвалидировать конкретный токен. То есть разлогинить пользователя с сервера.
2) Нельзя редактировать данные, которые зашифрованы в токен.
3) Нет простого способа продлевать время жизни токена. Он или вечный или на конкретное время, например на час и не продлевается автоматически. Продлевать токен возможно, но это будет уже не продление, а выпуск нового токена.

Способ хранения:
Незавимисо от того, какой способ выбран, хранить session_id и token мы можем как в куках, так и в localStorage. Оба способа имеют свои преимущества и недостатки.
Куки:
1) Автоматически отправляются на сервер
2) Имеют ограничение по длине (но это неважно в данном случае)
3) Необходимо использовать CSRF токен.
4) Нет риска кражи куки через XSS.
5) Куки доступны на сервере до того, как клиент прогружен. То есть, например, если у нас SPA сайт, то данные можно получать уже при первой загрузке страницы.

Токены:
1) Не нужно думать о CSRF атаках.
2) Нужно думать об XSS, чтобы токен не украли.
3) Данные можно получать только после загрузки клиента.

Подскажите, пожалуйста, что за минусы у кук в мобильных приложениях, а если проблемы именно с куками, то почему не хранить session_id где-то еще? Какие еще плюсы/минусы есть у обоих реализаций?

UPD: Вообще, анализаруя плюсы и минусы, я не вижу смысла использовать токены, там одни минусы.
А у себя в проекте я использую следующую схему:
При авторизации, генерирую хэш, который сохраняю авторизованному пользователю в БД. Хэш отправляю клиенту, сохраняю в LS. Никакого состояния (данных о пользователе) на сервере не храню. При каждом обращении отправляю с клиента этот хэш и на сервере получаю информацию о пользователе из БД по полученному хэшу.
Единственный минус для меня - это недоступность хэша при первом обращении к серверу (у меня SSR приложение). Но это можно исправить, переместив хранение хэша из localStorage в куки. В общем способ, который я использую, отличается от сессий тем, что на сервере не заводится никакого хранилища (файла сессии или записи сесии в БД).
Как называется способ, который я использую? И чем он хуже сессий, если сохранять данные в сессии не требуется?
  • Вопрос задан
  • 811 просмотров
Пригласить эксперта
Ответы на вопрос 2
iit
@iit
TeamLead + php/js разработчик
Все зависит от того кто и как будет обращаться к backend.

Если это другой сервер, мобильное приложение или SPA то лучше использовать токены - JWT как самый распространенный вариант.

В случае обычного сайта или SPA возможно использовать сессии.

Если используем обычные статические страницы + http api тогда сессия вполне нормальный вариант в том числе и для приложения по типу web-view.

Если используем SPA с REST api / Graphql тогда токены удобнее.

Что касается где хранить id пользователя в токене то самом JWT есть заголовок для этого. Вообще Jwt это 2 json + хэш/ключь слепленные вместе через base64.

Первый json - служебный в нем идет алгоритм и тип ключа, второй - настраиваемый и может содержать что угодно, правда для некоторых моментов например id токена (jti) или id сессии (sid) есть предопределенные заголовки. Полный их список тут

В вашем случае есть 2 варианта

1 - доступ по сессии
API и SPA требует сессию для защищенных методов, авторизация эту сессию предоставляет. Авторизация - может быть выполнена как обычной статической html с формой так и отдельным SPA.

2 - доступ по токену
В этом случае Авторизация реализуется в виде api на стороне сервера, и в виде токена
+ формы + логики авторизации на стороне клиента (Vue). Если токен есть - тогда есть доступ, если нет - то доступ только к методам регистрации и авторизации.
Чтобы не палить код той части приложения где есть логика и фронт закрытой части - можно использовать code-splitting - сперва подгружается форма авторизации а остальное грузиться тогда когда это нужно.

Есть правда еще более извращенные варианты вроде SPA с SSR на том-же Nuxt/Next/Express где пользователю токен а бэку на Go/JAVA/PHP уже токен приложения + токен пользователя.
Иногда стоит использовать OAuth2.0 и LDAP которые тоже довольно интересны.
Первый хорош на все случаи жизни, но только если используется куча связанных приложений/микросервисов а второй просто рай для бизнес-пользователей с Windows для какой-нибудь коробочной CMS.
Ответ написан
Комментировать
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
В общем способ, который я использую, отличается от сессий тем, что на сервере не заводится никакого хранилища (файла сессии или записи сесии в БД).
По факту вы храните запись в бд с ключем сесии, то есть не копируете данные в новое хранилище, а привязываете имеющиеся данные к сессии, по сути смешивая сущности(имхо). Плюс теряете возможность хранить состояния на сервере в случае когда они нужны. Плюс дергаете таблицу юзеров каждый раз когда нужно логинить/разлогинить пользователя, вместо удаления / создания записи со ссылкой на пользователей. Как кастомное решение норм, но в целом оно слишком... специфичное.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы