Добавляем Refresh Token

в 15:04, , рубрики: oauth, авторизация, информационная безопасность, Программирование, Разработка веб-сайтов, токены

Добавляем Refresh Token - 1

В прошлой статье я рассказывал про основы JWT. Если на пальцах, то это просто ключ, с помощью которого мы открываем дверь к приватным ресурсам. А что, если этот ключ украдут (точнее, сделают дубликат). Тогда кто-то еще сможет входить на сервер под вашим именем, причём мы об этом можем даже не узнать. Такого сценария мы не хотим допустить. Но что делать?

Повышаем безопасность

Предлагаю читателям перед тем, как двигаться дальше самостоятельно, подумать, что мы можем сделать с безопасностью.

Приведу несколько подходов, которые могут улучшить безопасность. Можете писать в комментариях, какие еще существуют подходы — я их добавлю.

  1. Использование https протокола, который обеспечивает защиту канала передачи данных через интернет. По сути, это обертка над http, которая накладывает дополнительные криптографические протоколы — SSL и TLS
  2. Добавление в payload информации об IP. Тогда токен с других IP не пройдет проверку. Но IP можно подделать, да и что делать с динамическими IP адресами или, когда пользователь подключается с телефона в кафешке или метро. Поэтому мы не будем использовать данный подход.
  3. Вместо HS256 использовать RS256. Это обеспечивает безопасность самого секретного ключа. Но с токенами все остается абсолютно как было. RS256 нам нужен, когда мы опасаемся передавать секретный ключ другим серверам, которые могут быть ненадежными. Мы им даем только инструмент проверки подлинности токена, что абсолютно бесполезно для злоумышленника.
  4. Использовать короткоживущие токены. Но тогда пользователю придется перелогиниваться каждый раз, когда у него истечет срок жизни. Пользователю это рано или поздно надоест и он уйдет с нашего ресурса.
  5. А что если всё-равно использовать короткоживущие токены, но дать ему еще один токен, цель которого лишь в том, чтобы получить новый короткоживущий токен без новой авторизации? Такой токен называется Refresh-токен и использовать его можно будет только один раз. Об этом и будет моя статья.

Вспомним, что такое JWT

JWT использует преимущества подхода цифровой подписи JWS (Signature) и кодирования JWE (Encrypting). Подпись не дает кому-то подделать токен без информации о секретном ключе, а кодирование защищает от прочтения данных третьими лицами.

Давайте разберемся, как они могут нам помочь для аутентификации и авторизации пользователя на сайте.

Аутентифика́ция (англ. authentication; от греч. αὐθεντικός [authentikos] – реальный, подлинный; от αὐθέντης [authentes] – автор) — процедура проверки подлинности. В нашем случае, мы проверяем логин + пароль на совпадение с записью в базе даных пользователей.

Авториза́ция (англ. authorization — разрешение, уполномочивание) — предоставление пользователю прав на выполнение определённых действий; а также процесс проверки (подтверждения) данных прав при попытке выполнения этих действий.

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

Виды токенов

  • Токены доступа (JWT) — это токены, с помощью которых можно получить доступ к защищенным ресурсам. Они короткоживущие, но многоразовые. В них может содержаться дополнительная информация, напрмер, время жизни или IP-адрес, откуда идет запрос. Все зависит от желания разработчика.
  • Рефреш токен (RT) — эти токены выполняют только одну специфичную задачу — получение нового токена доступа. И на этот раз без сервера авторизации не обойтись. Они долгоживущие, но одноразовые.

Основной сценарий использования такой: как только старый JWT истекает, то с ним мы уже не можем получить приватные данные, тогда отправляем RT и нам приходит новая пара JWT+RT. С новым JWT мы снова можем обращаться к приватным ресурсам. Конечно, рефреш токен тоже может протухнуть, но случится это не скоро, поскольку живет он намного дольше своего собрата.

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

const validateToken = token => {
    const [ header, payload, signature ] = token.split('.');
    return signature === HS256(`${header}.${payload}`, SECRET_KEY);
}

C другой стороны у нас есть рефреш, который позволяют нам обновить токен доступа без ввода пароля от пользователя, но в этом случае нам все-таки потребуется выполнить дорогую операцию обращения к серверу авторизации.

В заключение

Благодаря такому подходу мы уменьшаем задержку по времени обращения к серверу latency, да и сама серверная логика становится сильно проще. А с точки зрения безопасности, если у нас всё-таки украли токен доступа, то воспользоваться им смогут только ограниченное время — не больше времени его жизни. Чтобы злоумышленник смог пользоваться дольше — ему потребуется украсть еще и рефреш, но тогда настоящий пользователь узнает, что его взломали, поскольку его выкинет из системы. И стоит такому пользователю снова войти в систему, он получит обновленную пару JWT+RT, а украденные превратятся в тыкву.

Полезные ссылки

  1. Зачем нужен Refresh Token, если есть Access Token?
  2. Refresh Tokens: When to Use Them and How They Interact with JWTs
  3. More OAuth 2.0 Surprises: The Refresh Token

Автор: Борис Южаков

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js