[Из песочницы] Так зачем же все таки нужны Refresh токены в OAuth?
Эта тема довольно активно дискутируется — вот и на Stackoverflow вопрос есть и на Хабре тоже обсуждается. Собственно, именно обсуждение на Хабре и заставило меня высказаться.
Все предложенные комментаторами и авторами мнения касаются безопасности двухтокенного подхода. Безусловно, так и должно быть, ведь безопасность — это главное для фреймворка авторизации/аутентификации! Но будем откровенны — во многих случаях использования подход с двумя токенами не дает никакого выигрыша в защищенности по сравнению с простым и тупым подходом с одним токеном. Или этого сразу не видно…
«Refresh токен можно хранить более защищенно!» — можно и нужно, хотя почти никто так не делает.
«Access token передается по сети чаще — и вероятность его утечки больше» — полноте, мы ведь всегда используем TLS, правда?
«Утечка Ассеss токена на так страшна как утечка Refresh токена» — да, и это тоже правда, именно поэтому в браузер Refresh токен и не выдается…
Есть много нюансов, есть много сценариев использования, при которых использование разных токенов становится полезным, просто видно их не сразу!
Но есть и еще один аргумент, который я почему-то ни разу не встречал — хотя он, на мой взгляд, полностью объясняет, зачем же нужен Refresh токен и почему нельзя, абсолютно, категорически нельзя обойтись только Access токеном.
Производительность.
Причем речь идет не о сайте или приложении с миллионом–десятком миллионов пользователей, нет!
Давайте подумаем, как же должны работать с OAuth аутентификацией сервисы уровня Гугла, Фейсбука и Твиттера.
Вот получил бекенд этого Большого Сервиса Access токен. Как проверить его валидность?
Ну, можно поискать его в базе данных. Так как речь идет о Сервисе с Большой Буквы — то и База Данных будет большая, мощная, с Большой Буквы.
Да, похоже у нас с этой Базой будет проблема, правда? Давайте разместим ее в inMemory, давайте добавим несколько реплицируемых копий… Справимся? Наверное…
Или знаете что? Давайте будем хранить всю информацию о токене в нем самом! Так и называется — self-contained токен. Мы его конечно, при создании зашифруем и подпишем –, а при получении расшифруем и проверим подпись. И извлечем все что надо: имя пользователя, его права и срок действия токена.
Да, такой подход, кажется и в самом деле будет работать! Не нужно чудовищно быстрой и ответственной Базы Данных Токенов! Любой наш сервер (а их у нас много, мы ведь распределенные!) легко и просто проверяет валидность токена и извлекает из него необходимую информацию о правах и доступах.
Так…, а что мы будем делать если пользователь изменил пароль? Надо ведь все старые токены инвалидировать? Что будем делать, если администратор заблокировал пользователя или изменил его права?
Да, а ведь без базы данных-то и не обойтись! Ну так и давайте проверять права пользователя не всегда –, а иногда, с некоторыми разумными интервалами. Ну скажем в момент обновления токенов — то есть раз в час!
Да, так оно и работает. Программисты, имплементирующие OAuth на стороне сервера аутентификации имеют выбор — они могут проверять права владельца токена каждый раз при получении Access токена –, а могут делать это только изредка, при создании новой пары токенов.
Преимущества и недостатки обоих подходов очевидны — ну, а Большие Сервисы и выбора-то не имеют — и работают по схеме self-contained токенов.
Вот, оказывается, и еще одно достоинство этого сложного, но такого гибкого фреймворка — oAuth 2.0!