Разбираемся в кукисах, сессиях и токенах

Коротко:

Cookies (далее – кукисы) – это пары ключ:значение, передаваемые сервером в заголовке. Их может быть несколько: один кукис username, и один userrole, к примеру. Кукисы работают, когда у вас лень, или когда можно не особо заморачиваться c безопасностью, ведь в них передается много чего. 

Сессии (иначе, сеансы; sessions) – это “как кукисы”, но вместо передачи реальных данных в кукисах, передается только маркер (иначе говоря, идентификатор, “айдишник”, ID). Так называемый session-id. В таком подходе, клиент не знает, что передается в сессии, только сервер имеет доступ. В этом методе, backend должен знать, какая сессия сейчас активна. То есть, backend в этом подходе считается “stateful”, то есть “работает от состояния”. 

Токены – в чем-то похожи на обычные, “несессионные” кукисы. Токены хорошо шифруются, взломать-подменить сложно. Бекэнд в этом подходе – stateless, не зависит от состояния: токен, взятый из одного бекэнда, будет работать на любом другом бекэнде, то есть этот подход “горизонтально масштабируемый”. 

Подробнее:

Чтобы понять нюансы применения кукисов, сессий и токенов, нужно вспомнить, где они применяются. Итак, нам надо войти в свой аккаунт в банке. Стандартом является окно входа, здесь мы вводим логин и пароль, и кнопка с надписью “Отправить” или “Войти”, для отправки пары логин/пароль на сервер банка.

Сервер, приняв эту пару, теперь должен проверить, кто вы. Для этого производится сопоставление с базой; если введенная вами пара совпадает с имеющимися в базе (и ничего не вызывает подозрений), то сервер перенаправит на главную страницу аккаунта. 

При этом, в базе данных создается сессия; а также, в БД добавляется событие успешного входа. Клиенту, то есть вам, как бы в обмен на пару логин/пароль отправляется кукис, содержащий session_id. 

Таким образом, сервер хранит информацию о сессии в своей базе данных, в то время как вам отправляет только кукис c идентификатором, session_id. Кукис сохраняется в вашем браузере. Session_id генерируется рандомно – поэтому угадать его невозможно. После выхода из своего аккаунта в банке, сессия удаляется из сервера, но при этом сервер передает в браузер инструкцию об удалении кукиса с session_id.

При следующем заходе в аккаунт, браузер автоматически отправляет кукис с session_id, и сервер оценивает этот кукис на валидность (неподмененность, непросроченность). Важно понимать, что в этом следующем заходе на сервер, пара логин/пароль уже не нужна для авторизации. 

Кукисы можно сравнить с хранением данных о клиенте на членской карте в спортзале. Там хранится номер – membershipID, и некоторые другие уточняющие детали. Когда карту проводят через приемное устройство на двери, оно проверяет карту на валидность, и принимает решение, впускать ли. Так же и с кукисами: их session_id срабатывают только на этом сайте, подобно тому как нельзя войти в офисное здание, проводя картой для спортзала; кукисом для одного сайта нельзя воспользоваться для входа на любой другой сайт.

Банковский сервер поддерживает сессию в *живом* состоянии до тех пор, пока вы проявляете активность на банковском сайте. Если не производить никаких действий достаточно долго, сервер зафиксирует это, и спросит логин/пароль, когда попытаетесь войти снова. 

Итак, этот подход называется “cookie-based authentication”. Этот метод предполагает создание сессии на сервере, для обработки авторизации. Кукис – лишь носитель для передачи маркера (sessionID). Кукисы используются, потому что это просто. И удобно – браузер всегда отправляет кукисы после каждого запроса от сервера. То же и с картой для спортзала: она удобна, (“вынул да провел”), нет нужды предъявлять свой бумажный “аусвайс” охраннику на входе. Конечно, можно и скопировать фотографию карты на смартфон и показывать эту фотографию, это без разницы, носитель не имеет значения, концепция та же. Банк хранит информацию о сессии у себя на сервере, вы ее видеть не можете, но может и хранить другую информацию у вас в браузере смартфона, а конкретно в кукисах. Там обычно хранится не только сессионный ID, но и дополняющая, уточняющая информация, которая также важна для удобства – последние посещенные страницы на сервере, размер шрифта на странице у конкретного клиента, или скажем выделение цветом какого-то уведомления.

Почему же серверы не хранят в кукисах все данные?

Теперь рассмотрим вопрос, почему серверы не “сгружают” в кукисы всю информацию о сессиях и клиенте. 

Быстрый ответ: потому что кукисы ненадежные. Уточним: недостаточно надежные, чтобы доверять им в полной мере. Ведь кукисы приходят от клиента, а иногда от того, кто клиентом лишь назвался. Поэтому сервер работает со своими базами данных, которые (опять же, в идеале) – наполнены только надежными данными. 

Есть и альтернатива. Хранить данные о клиенте – у клиента, и подписывать их. То есть, удостоверять. В этом подходе, каждый кто обладает подписью, может быстро проверить, подменяли ли данные. Простой способ проверить это – JSON WEB TOKENS. 

Авторизация кукисами отлично работала много-много лет, но она медленно устаревает, особенно в специфических сферах, например финансы.

Представим, что вам нужно поставить в смартфон некое финансовое приложение, для контроля своих расходов. Естественно, для этого нужен доступ к банковскому счету. Но вы не хотите давать этому приложению свой логин/пароль к банковскому счету. Хотя бы потому, что компания, которая создает приложения – это по умолчанию не банковская, не “серьезная”. В этом случае банк переправляет вас к странице с вопросом “Эй, тут какое-то приложение запрашивает разрешение на доступ к вашим банковским транзакциям, разрешить?”. Если вы ответите “Да”, приложение получит токен с доступом к транзакциям. 

Однако, приложение всего лишь видит список транзакций, и оно не сможет “самоуправно” сделать переводы между счетами, и даже видеть то обилие деталей о счетах, которые видны вам на сайте банка.

Этот токен как бы аналогичен рандомно сгенерированному паролю. Еще лучше сравнить токен с выдачей однодневного пароля к Wi-Fi в гостинице.

 Аналогичная процедура работает всякий раз, когда Facebook или Google показывают диалог: “Разрешать ли этому сайту доступ к Вашему профилю в Facebook?”

Таким образом, в этом подходе вы никогда не отправляете свой логин/пароль; и в любой момент вы можете отозвать разрешение на доступ к своему банковскому аккаунту. Просто сгенерированный ранее токен объявляется более недействующим. 

Вообще, в таких случаях чаще применяется механизм OpenID, но и его аналог JSON Web Tokens применяется очень часто.

Еще раз о важной разнице между токеном и session_id в кукисе

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

Если идет речь о JWT-токенах, то такой токен, помимо “своей” нагрузки, содержит и информацию о сессии, и актуальные данные о клиенте. 

Когда говорим о токенах, важно заметить, что этот тип взаимодействия предполагает наличие нескольких сторон, среди которых могут быть не вполне надежные, точнее “не вполне доверяющие друг другу”. То есть, вы доверяете своему банку, передаете туда логин/пароль, но, вполне естественно, боитесь передавать их приложению, скачанному в аппсторе, или вообще найденному на файло-свалке. 

Еще один нюанс: токен имеет ограниченное “время жизни”, то есть срок валидности. После “просрочки” токена, генерируется новый; как принято говорить – refreshed, “освежается.”

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

Токены отправляются посредством HTTP-заголовков, но не в кукисах, поскольку сейчас большая часть взаимодействий происходит в браузерах смартфонов, и кукисы тут уже не очень удобны. 

Как говорится, “Кукисы отправляются как HTTP-заголовки, но браузеры обрабатывают их по другому, не как другие заголовки”

Итак

В целом, распространены оба подхода, как сессии с кукисами, так и токены. Часто они применяются параллельно в проекте. К примеру, сессия с кукисами – на сайте, а токены – в приложении той же компании. Поэтому нужно знать, как работают оба эти подхода.

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Scroll to Top