Аутентификация токена с помощью Volley
Если у меня есть сервер, на котором я аутентифицирую имя пользователя/пароль и получаю токен аутентификации для последующих запросов, какой был бы лучший подход к решению этой проблемы?
Поток должен быть таким:
- Запрос на запуск
- Если у нас нет токена аутентификации - получите его с именем пользователя и паролем
- Сделать запрос с помощью токена авторизации
- Если запрос завершился неудачно, поскольку токен истек, получите новый токен аутентификации с именем пользователя и паролем
- Запросить повторный запрос с новым токеном аутентификации
- Завершить
Я заметил, что у Volley уже есть что-то, что может решить эту проблему - Authenticator https://android.googlesource.com/platform/frameworks/support/+/4474bc11f64b2b274ca6db5a1e23e8c1d143d5fa/volley/src/com/android/volley/toolbox/Authenticator.java Он содержит методы getAuthToken() и invalidateAuthToken(), которые были бы именно то, что я хочу. Но кажется, что он никогда не использовался в библиотеке вообще.
Ответы
Ответ 1
Я использовал залп для системы аутентификации с использованием токенов Longlive (LLT) и Shortlive (SLT).
Я сделал это вручную, но на самом деле это было не так много работы, как только вы все выложили.
У всех подпрограмм защищенных запросов есть baseSecureRequest, которые могут обрабатывать этот механизм токена, общий для всего защищенного запроса, в его onResponse() и onErrorResponse().
Он становится немного стилем node.js, где запросы отправляют другие запросы и ждут обратные вызовы.
В приложении может быть дюжина экранов, причем только половина требует доступа к авторизации - поэтому каждый экран должен быть не осведомлен о требованиях своего запроса.
Сценарий A
- Мы пытаемся отправить безопасный запрос. Мы замечаем, что у нас нет SLT в
памяти, поэтому сделайте TokenRequest.
- TokenRequest onResponse() сохраняет
этот токен в память (пусть один синтаксический менеджер сеанса удерживает его или
аналогичный omni-present class)
- Теперь обратный вызов оригиналу
объект запроса конкретного класса, чтобы продолжить новый обновленный токен.
Сценарий B
-
Мы отправляем безопасный запрос, но наш SLT устарел (истек)
-
Сервер возвращает код ошибки или msg, который вы можете поймать в
общий onErrorResponse() вашего baseSecureRequest.
-
В этом onError() вы отправляете объект refreshTokenRequest(), который
пытается обновить SLT в памяти, запросив новый SLT с сервера с использованием LLT.
-
onResponse() refreshTokenRequest теперь может возвращать
оригинальный запрос на повторную отправку.
- однако onErrorResponse() должен, вероятно, отказаться от всего, потому что есть шансы
все, что не является ошибкой подключения - это ошибка, вызванная
недействительный LLT. Если вы продолжаете пытаться обновиться с плохой LLT, вы никогда не выберетесь.
Ответ 2
- Возможно, вы захотите использовать API AccountManager в Android для аутентификации и авторизации. Вы можете следить за блогом здесь.
- Для реализации на стороне сервера OAuth 2.0 вы можете прочитать проект IETF V2-31 здесь.
- Для лучшего понимания OAuth 2.0 вы можете прочитать блог Nitesh Kumar .
- Для реализации OAuth 2.0 на стороне сервера вы можете использовать Apis Autherization Server repo в Github.
- Дополнительную опцию реализации можно найти на веб-сайте OAuth 2.0 здесь.
Ответ 3
Вы видели этот пост в блоге? https://smaspe.github.io/2013/06/06/volley-part2.html
Демонстрирует простой способ переопределения объекта запроса для использования токенов Twitter.
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
String auth = "Basic "
+ Base64.encodeToString((TwitterValues.CONSUMER_KEY
+ ":" + TwitterValues.CONSUMER_SECRET).getBytes(),
Base64.NO_WRAP);
headers.put("Authorization", auth);
return headers;
}
Ответ 4
В моем случае я изменил "базовую" аутентификацию на токен-аутентификацию следующим образом:
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<>();
//todo Esta es una authenticación basica (usuario y contraseña)
/*String credentials = USER+":"+PASSWORD;
String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
headers.put("Authorization", auth);*/
//todo Esta es una authenticación con token (por tiempos)
headers.put("Authorization", "Bearer" + " " + "tokenString");//App.getToken()
return headers;
}
Что я сделал, так это сохранил Логин в глобальной статической переменной, а затем смог использовать его.
Ответ 5
getToken()
не удалось. Ошибка статуса BAD_AUTHENTICATION
Я также столкнулся с той же проблемой.
Решение: проверьте, входит ли устройство в вашу учетную запись Google.