Как называется такая аутентификация и как выбрать правильный способ?
Прочел несколько статей по способам аутентификации. В голове немного каша и осталось несколько вопросов. Сессии.
Сессия - это способ сохранения состояния на сервере между запросами пользователя. На сервере создается сессия (обычно это файл или запись в БД или в памяти). Это сессия имеет 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 в куки. В общем способ, который я использую, отличается от сессий тем, что на сервере не заводится никакого хранилища (файла сессии или записи сесии в БД).
Как называется способ, который я использую? И чем он хуже сессий, если сохранять данные в сессии не требуется?
Ну как же я использую токены, если я ничего не шифрую, ничего в них не храню и могу инвалидировать хэш, выданный пользователю? От токена одно название остается.
В общем способ, который я использую, отличается от сессий тем, что на сервере не заводится никакого хранилища (файла сессии или записи сесии в БД).
По факту вы храните запись в бд с ключем сесии, то есть не копируете данные в новое хранилище, а привязываете имеющиеся данные к сессии, по сути смешивая сущности(имхо). Плюс теряете возможность хранить состояния на сервере в случае когда они нужны. Плюс дергаете таблицу юзеров каждый раз когда нужно логинить/разлогинить пользователя, вместо удаления / создания записи со ссылкой на пользователей. Как кастомное решение норм, но в целом оно слишком... специфичное.
У меня SPA сайт на vue с сервером на PHP. В личном кабинете пользователя он видит, сколько "сессий" у него открыто. Как в телеграме, он видит что логинился он столько то раз с таких то браузеров. И может удалить любую сессию.
Именно по этой причине я и выбрал такой способ. Потому что удалять сессии пользователя в PHP по умолчанию нельзя, нужно как-то синхронизировать session_id с id пользователя и где-то хранить. А это нужно писать. В итоге тоже получился бы велосипед.
При авторизации, генерирую хэш, который сохраняю авторизованному пользователю в БД. Хэш отправляю клиенту, сохраняю в LS. Никакого состояния (данных о пользователе) на сервере не храню. При каждом обращении отправляю с клиента этот хэш и на сервере получаю информацию о пользователе из БД по полученному хэшу.
То есть вы сделали сессию, но ключ храните в лс, а от сессии оторвали данные. в чем профит? В смысле в отличии от стандартного механизма?
ThunderCat, В стандартном механизме мне пришлось бы сохранять id сессий в БД, чтобы давать возможность удалять сессию и разлогинивать пользователя. А так как данные в сессии мне не нужны, показалось проще и понятнее сделать свою реализацию.
ThunderCat, для хранения идентификатора я бы сделал такую же работу, согласен с недоумением. Но мне не нужно хранить состояние, а сессия по умолчанию создаёт файл для каждого нового подключения. Причем не только для авторизованных пользователей, но и для обычных посетителей, которым вообще не нужны никакие права. В моей реализации этого нет.
А ещё я прочел статью https://m.habr.com/ru/company/dataart/blog/262817/ и в этой статье на мой способ больше всего похожа "аутентификация по ключам доступа". И ведь действительно, состояние не хранится, ключ выдается после авторизации, ключ можно удалять, продлевать, редактироваться на его основе права пользователя и тп.
Правильно ли будет сказать, что то что я у себя сделал - это ключи доступа, а не сессия без состояния?
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.