Зачем нужен Refresh Token, если есть Access Token?

в 8:17, , рубрики: oauth, voximplant, Блог компании Voximplant, информационная безопасность, Программирование, Разработка веб-сайтов, разработка мобильных приложений, токены

Зачем нужен Refresh Token, если есть Access Token? - 1Недавно мы в Voximplant улучшали авторизацию в SDK. Посмотрев на результаты, я несколько опечалился, что вместо простого и понятного токена их стало две штуки: access token и refresh token. Которые мало того что надо регулярно обновлять, так еще документировать и объяснять в обучающих материалах. Помня, что в OAuth два токена нужны в основном из-за разных сервисов, на которых они используются (даже вопрос на stackoverflow есть), а у нас такой сервис один, я несколько офигел и пошел на второй этаж вытрясать души из разработчиков. Ответ получился неожиданным. Его нет на stackoverflow. Зато он есть под катом.

Зачем вообще нужны токены

При разработке приложений, общающихся с сервером, обычно вылезают следующие этапы:
Зачем нужен Refresh Token, если есть Access Token? - 2

  1. Приложение разрабатывает один разработчик, нет ни идентификации, ни аутентификации, ни авторизации (кстати, рекомендую замечательную хабрастатью на эту тему от DataArt), запросы напрямую ходят к эндпоинтам сервера, разработчик счастлив.
  2. Появляется второй разработчик, или тестировщик, или заказчик. Серверу становится важно знать, кто именно отправляет запрос. Добавляется шаг идентификации: простенькое окно «представьтесь» перед стартом приложения и крики «кто опять заходил под тремя единичками и все сломал?!?»
  3. Когда команда чуток устанет от «кто заходил под тремя единичками», на backend запилят форму регистрации с логином-паролем, которая будет проверять на уникальность логина. В таком виде продукт и будет разрабатываться до первой бета версии.
  4. В первой бета версии окажется, что сохранять пароль в plain text на устройстве — это как-то не очень безопасно. У сферического пользователя в вакууме один пароль от большинства сервисов, и очень не хочется быть крайним, через кого у пользователя взломали мейл, вконтактик и все остальное. Начинаются поиски решения «что бы такое сделать, чтобы пароль в явном виде не хранить». И через некоторое время команда приходит к тому или иному варианту «auth token».

Зачем нужен первый токен

Зачем нужен Refresh Token, если есть Access Token? - 3Есть много разных токенов. Обычные, криптографические, «access key», «session token», разные схемы получения, использования и revoke. При этом одна из ключевых идей заключается в том, что если кто нехороший получит чужой токен, то самое неприятное, что случится — это доступ похитителя к сервису, от которого токен похищен. Пароль, тот самый, который один на все сервисы, похититель не получит. А пользователь, если поймет, что кроме него к сервису получил доступ кто-то другой, может токен отозвать. После чего получить себе новый, имея логин и пароль.

Зачем нужен Refresh Token, если есть Access Token? - 4

Зачем нужен второй токен

В OAuth 2 и некоторых других схемах авторизации (например, у нас) есть не один, а целых два токена. Первый, access token, используется при запросах к серверу (например, при логине). У него есть два свойства: он многоразовый и короткоживущий. Наш, к примеру, живет 48 часов, а у кого-то 30 минут. Время выбирается на основании того, как используется сервис. Второй, refresh token, используется для обновления пары access и refresh токенов. У него тоже есть два свойства, обратные первому токену: он одноразовый и долгоживущий. Совсем долгоживуший, наш живет месяц.

Схема использования у токенов следующая:
Зачем нужен Refresh Token, если есть Access Token? - 5

  • Пользователь логинится в приложении, передавая логин и пароль на сервер. Они не сохраняются на устройстве, а сервер возвращает два токена и время их жизни
  • Приложение сохраняет токены и использует access token для последующих запросов
  • Когда время жизни access token подходит к концу (приложение может само его проверять, или дождаться пока во время очередного использования сервер ответит «ой, всё»), приложение использует refresh token, чтобы обновить оба токена и продолжить использовать access token

Примерно так это все объяснено в документации OAuth, на Википедии, в нашей документации. И такое объяснение не отвечает на вопрос нафига?!? Зачем нужны два токена, если можно обойтись одним? В вопросе на stackoverflow даны несколько объяснений уровня «ну, access token можно менее надежно хранить чем refresh token и не бояться использовать вне HTTPS соединений» или «refresh token используется для доступа к заведомо безопасному сервису, а access token'ом потом можно тыкать во всякие подозрительные места и не очень бояться, что его сользую». Это может быть разумно для авторизации через Facebook и последующего использования без HTTPS. Но у нас-то везде HTTPS! И сервис у нас тоже один, наш. Зачем нам второй токен?

Зачем на самом деле нужен второй токен

Зачем нужен Refresh Token, если есть Access Token? - 6Все оказалось и проще, и сложнее чем я думал. Следите за руками:

Случай 1: Боб узнал оба токена Алисы и не воспользовался refresh

В этом случае Боб получит доступ к сервису на время жизни access token. Как только оно истечет и приложение, которым пользуется Алиса, воспользуется refresh token, сервер вернет новую пару токенов, а те, что узнал Боб, превратятся в тыкву.

Случай 2: Боб узнал оба токена Алисы и воспользовался refresh

В этом случае оба токена Алисы превращаются в тыкву, приложение предлагает ей авторизоваться логином и паролем, сервер возвращает новую пару токенов, а те, что узнал Боб, снова превратятся в тыкву (тут есть нюанс с device id, может вернуть ту же пару что и у Боба. В таком случае следующее использование refresh токена превратит токены Боба в то, что изображено справа).

Зачем нужен Refresh Token, если есть Access Token? - 7Таким образом, схема refresh + access токен ограничивает время, на которое атакующий может получить доступ к сервису. По сравнению с одним токеном, которым злоумышленник может пользоваться неделями и никто об этом не узнает.

Автор: Voximplant

Источник

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


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