Как получить новый токен доступа в OpenID Connect/OAuth2 Implicit Flow
В настоящее время я использую OpenID Connect/Oauth2 Implicit Flow в мобильном приложении. Я открываю веб-представление для пользователя, чтобы войти в систему и получить маркер доступа и срок действия. Однако, когда срок действия маркера доступа истекает, нужно ли просить пользователя снова войти в систему? Или есть способ получить новый токен доступа в режиме без вывода сообщений, используя текущий, без ошибок пользователя. Я предполагаю, что другой вариант - установить истечение срока действия токена очень долго, но я прочитал, что это плохая идея.
Я что-то здесь упускаю?
2 ответа
Поскольку неявный поток не отправляет токен обновления (как описано в разделе 9 RFC6746), использование токенов обновления невозможно. Но в качестве обходного пути можно использовать учетные данные клиента для получения токена доступа.
Жизнеспособное решение состоит в том, чтобы сначала следовать неявному потоку и аутентифицировать клиента. Затем можно использовать грант аутентификации клиента для выполнения необходимых вызовов API.
Пример запроса (из RFC6749)
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
rant_type=client_credentials
Образец Resposne (из RFC6749)
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"example_parameter":"example_value"
}
PS - Если вы используете поток кода авторизации, вы можете использовать refresh_token
получить новый токен доступа. Как запрос должен быть сформирован, можно узнать из документации OAuth2. Обратите внимание, что для этого ваш авторизационный ответ должен содержать `refresh_token.
Токен обновления должен быть защищен как учетная запись пользователя. Больше можно почитать из документации keycloak отсюда
Образец запроса и ответа (из RFC6749)
Запрос
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
отклик
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "TlBN45jURg",
"token_type": "Bearer",
"refresh_token": "9yNOxJtZa5",
"expires_in": 3600
}
Рекомендуемый способ - использовать внешний браузер и поток кода авторизации. Проверьте OAuth 2.0 для собственных приложений RFC. Для Android также есть вспомогательная библиотека AppAuth. С помощью этого потока вы можете использовать токен обновления для получения нового токена доступа, но есть проблема с секретом клиента (обычно необходим для доступа к конечной точке токена), потому что вы не можете сохранить его в мобильном приложении (это описано в RFC).
Если вы решили придерживаться WebView и неявного потока, что небезопасно (ваше приложение может видеть пароль), вы можете использовать ту же технику, что и в приложениях JavaScript - запросите новый токен с /auth?...&prompt=none
URL, который будет возвращать новый токен, не спрашивая у пользователя учетные данные, если у него все еще есть открытый сеанс.