В данной заметке рассматривается работа JWT с симметичным алгоритмом шифрования (HS256/HS384/HS512)
Аутентификация(authentication, от греч. αὐθεντικός [authentikos] – реальный, подлинный; от αὐθέντης [authentes] – автор) - это процесс проверки учётных данных пользователя (логин/пароль). Проверка подлинности пользователя путём сравнения введённого им пароля с паролем, сохранённым в базе данных пользователей;
Авторизация(authorization — разрешение, уполномочивание) - это проверка прав пользователя на доступ к определенным ресурсам.
Например после аутентификации юзер sasha получает право обращатся и получать от ресурса "super.com/vip" некие данные. Во время обращения юзера sasha к ресурсу vip система авторизации проверит имеет ли право юзер обращатся к этому ресурсу (проще говоря переходить по неким разрешенным ссылкам)
Собственно п.5 и есть процесс авторизации.
Дабы не путатся с понятиями Authentication/Authorization можно использовать псевдонимы checkPassword/checkAccess(я так сделал в своей API)
JSON Web Token (JWT) — содержит три блока, разделенных точками: заголовок(header), набор полей (payload) и сигнатуру. Первые два блока представлены в JSON-формате и дополнительно закодированы в формат base64. Набор полей содержит произвольные пары имя/значения, притом стандарт JWT определяет несколько зарезервированных имен (iss, aud, exp и другие). Сигнатура может генерироваться при помощи и симметричных алгоритмов шифрования, и асимметричных. Кроме того, существует отдельный стандарт, отписывающий формат зашифрованного JWT-токена.
Пример подписанного JWT токена (после декодирования 1 и 2 блоков):
{ «alg»: «HS256», «typ»: «JWT» }.{ «iss»: «auth.myservice.com», «aud»: «myservice.com», «exp»: «1435937883», «userName»: «John Smith», «userRole»: «Admin» }.S9Zs/8/uEGGTVVtLggFTizCsMtwOJnRhjaQ2BMUQhcY
Токены предоставляют собой средство авторизации для каждого запроса от клиента к серверу. Токены(и соотвественно сигнатура токена) генерируются на сервере основываясь на секретном ключе(который хранится на сервере) и payload'e. Токен в итоге хранится на клиенте и используется при необходимости авторизации како-го либо запроса. Такое решение отлично подходит при разаработке SPA.
При попытке хакером подменить данные в header'ре или payload'е, токен cтанет не валидным, поскольку сигнатура не будет соответствовать изначальным значениям. А возможность сгенерировать новую сигнатуру у хакера отсутствует, поскольку секретный ключ для зашифровки лежит на сервере.
access token - используется для авторизации запросов и хранения дополнительной информации о пользователе (аля user_id, user_role или еще что либо, эту информацию также называет payload)
refresh token - выдается сервером по результам успешной аутентификации и используется для получения нового access token'a и обновления refresh token'a
Каждый токен имеет свой срок жизни, например access: 30мин, refresh: 60дней
Поскольку токены это не зашифрованная информация крайне не рекомендуется хранить в них такую информацию как пароли
expires_in
поле, в unix timestamp). Также в payload refresh token'a добавляется user_id"accessToken": "...",
"refreshToken": "...",
"expires_in": 1502305985425
expires_in
)и если оно истекло использует refresh token чтобы обновить ОБА токена и продолжает использовать новый access tokenКлючевой момент что в момент рефреша то есть обновления access token'a обновляются ОБА токена. Но как же refresh token может сам себя обновить, он ведь создается только после успешной аунтефикации ? refresh token в момент рефреша сравнивает себя с тем refresh token'ом который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. Внимание при обновлении refresh token продливается также и его срок жизни.
Возникает вопрос зачем refresh token'y срок жизни, если он обновляется каждый раз при обновлении access token'a ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.
С такой схемой юзер сможет быть залогинен только на одном устройстве. Тоесть в любом случае при смене устройства ему придется логинится заново.
auth/refresh-token
URL refresh tokenexpires_in
access token'а клиентуПроблема: Поскольку refresh token продлевает срок своей жизни каждый раз при рефреше токенов >> хакер пользуется токенами до тех пор пока юзер не залогинится.