Howtojs

JWT vs Session

10 апреля 2021 г. • ☕️☕️ 8 мин.

JWT

Начнем с того, что JWT и Session сравнивать некорректно, как сравнивать коробку и автобус.

Что нужно сравнивать?

Способ аутентификации и хранения локального (клиентского) состояния.

Что такое аутентификация?

Аутентификация, это процесс в котором пользователь подтверждает то, кем он является.

С помощью чего работает аутентификация?

Пароли, одноразовые коды, токены, биометрия (отпечаток пальца, сканирования лица).

Пример аутентификации

Когда мы приходим в государственную организацию, нас просят показать паспорт, для подтверждения личности. Работник сравнивает фотографию с реальностью, а также проверяет подлинность паспорта по различным критериям.

Когда мы делаем запрос на сервер, он попросит нас предоставить username и password. В процессе аутентификации, сервер проверит в базе данных, что пользователь с данным username существует и пароль является верным.

Вот только вводить пароль на каждый запрос надоест.

Тыжпрограммист, можно это автоматизировать.

Можно же сохранить username и password в какое-нибудь хранилище (cookie/local storage/file) и сделать так, что браузер или какое либо другое приложение будут автоматически их отправлять на каждый запрос.

Какие здесь проблемы?

Данные из хранилища можно украсть.

Данные можно перехватить по пути.

Тот кто получит доступ к данным, сможет действовать от нашего лица.

Что можно придумать?

При вводе username и password, можно генерировать “секретную строку”, назовем ее токен (Token). Токен возвращается клиенту, клиент его сохраняет у себя в локальном хранилище, а потом при каждом последующем запросе, аутентифицирует себя добавляя данный токен, например, в заголовки HTTP запроса.

Пример токена

F2QT4fwpMeJf36

Как сервер проверяет подлинность токена?

Токен можно сохранить в базе данных сервера, ассоциировать его с пользователем, а при каждом запросе, проверять наличие токена и находить связанного пользователя.

Есть и другой подход, мы можем записать информацию о пользователе прямо в токен, закодировать его в base64 и подписать (sign) - это и есть JWT.

Пример JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Так как JWT подписан, при его модификации он не пройдет проверку подлинности на сервере.

У любого токена может быть время жизни, после которого он перестает работать.

C JWT серверу не нужно каждый раз обращаться в базу данных, т.к все данные хранятся в токене.

Нельзя просто взять и инвалидировать JWT в сравнение с обычным токеном, который хранится в базе данных.

Как сюда относится Session и что это такое?

На клиентском приложении Mobile App/Desktop App/SPA - у нас есть локальное хранилище данных (local storage/file/database). В нем мы можем хранить локальное состояние клиента (токен/язык/настройки фильтрации/кэш).

Если же у нас классический веб-сайт, которой рендерится на сервере (SSR - сервер возвращает готовый HTML браузеру) и не использует JavaScript, как клиент может сохранить локальное состояние, если например открыть и закрыть вкладку? Никак.

Только сервер может манипулировать клиентским состоянием, с использованием cookie. В cookie мы можем сохранить те же данные (user_id, язык, фильтры), но для простоты и безопастности, мы так же можем сохранить эти данные (локальное состояние клиента) в БД сервера, а клиенту отправить одну “куку” с id записи. Это и есть сессии.

Сессии позволяют, сохранять локальное состояние клиента (классического веб-сайта) между несколькими запросами, даже для неаутентифицированного пользователя.

Сессия - это объект в каком-либо хранилище (БД/Cookie/Файл), который привязан к текущему запросу.

При создании сессии, сервер генерирует строку sessionId и возвращает ее в ответе на запрос (чаще всего в cookie).

Каждый последующий запрос, клиент должен присылать серверу sessionId, а сервер найдет сессию по sessionId, так мы установим связь, между последовательными запросами.

Раз сессия это объект для хранения локального клиентского состояния, можем ли мы туда сохранить информацию о текущем пользователе для аутентификации, например user_id ? - Да.

Но ведь sessionId либо токен можно тоже украсть?

Можно, только их легче удалить или сделать невалидным, чем проходить процесс смены пароля.

Так же объект сессии, либо токен, можно сделать “короткоживущим”, значит, что даже в случае кражи, злоумышленник сможет им воспользоваться только в короткий промежуток времени.

Можно ли использовать сессии для других клиентских приложений)?

В теории Mobile App/Desktop App/SPA ничего не мешает имитировать поведение браузера и использовать cookie c серверными сессиями. Но зачем? Ведь у них есть свое локальное хранилище.

Что в итоге использовать?

Если у вас классический веб-сайт, где сервер возвращает HTML - sessions, они для этого и были придуманны.

Если сервер возвращает только данные json/xml/... - а клиентом может быть любое другое приложение - token.