2016-02-06 5 views
5

Я пытаюсь использовать Retrofit (2.0.0-beta3), но при использовании Authenticator для добавления токена я не могу получить данные от синхронного вызова. Наш журнал в фоновом режиме показывает много попыток входа в систему, но я не могу получить данные из тела, чтобы фактически добавить в заголовок.Android - Модернизация 2 - Результат аутентификатора

public static class TokenAuthenticator implements Authenticator { 
    @Override 
    public Request authenticate(Route route, Response response) throws IOException { 
     // Refresh your access_token using a synchronous api request 
     UserService userService = createService(UserService.class); 

     Call<Session> call = userService.emailLogin(new Credentials("handle", "pass")); 

     // This call is made correctly, as it shows up on the back-end. 
     Session body = call.execute().body(); 

     // This line is never hit. 
     Logger.d("Session token: " + body.token); 

     // Add new header to rejected request and retry it 
     return response.request().newBuilder() 
       .header("Auth-Token", body.token) 
       .build(); 
     } 
    } 

Я не совсем уверен, почему он даже не распечатывает ничего. Любые советы о том, как решить эту проблему, будут очень благодарны, спасибо, что нашли время, чтобы помочь.


Это те источники, которые я читал о том, как реализовать модернизацию.

Использование Authenticator:

Выполнение синхронных вызовов с Модернизированный 2:

+1

вы уверены, что gson сконфигурирован таким образом, он может понять ваш класс Session? – gropapa

+1

Вызов электронной почты (...) асинхронно работает, поэтому я не думаю, что это проблема с gson. Есть ли простой способ рассказать, что происходит с этим звонком? Я не вижу никаких ошибок или чего-то еще. –

ответ

5

У меня есть аналогичный аутентификатор, и он работает с 2.0.0-beta2.

Если вы получаете много попыток входа в систему от вашего Authenticator, я предлагаю вам убедиться, что при синхронном вызове вы не используете аутентификатор с этим вызовом. Это может закончиться в цикле, если также ваш «emailLogin» терпит неудачу.

Кроме того, я бы рекомендовал добавить loggingInterceptor, чтобы увидеть все Trafic к серверу: Logging with Retrofit 2

+1

Спасибо за ваш ответ, и я получил его, чтобы добавить в токены; однако каждый раз, когда я пытаюсь вызвать другой сетевой вызов, он делает то же самое, поэтому я думаю, что заголовок не переносится между вызовами. Как сохранить/установить заголовок для каждого вызова? –

+1

Я специально храню токен в базе данных и добавляю токен в заголовок «Авторизация» для всех вызовов. добавьте это к вашим вызовам и дайте токен в качестве параметра: @Header («Авторизация») String bearerToken, –

+1

Итак, я бы изменил вызов на «Call getUser (токен String) (@ Authorization); », но каждый раз, когда я его называю, мне нужно будет пройти в токен, это имеет смысл. Но есть ли более чистый способ сделать это? Может быть, использовать перехватчик или каким-то образом обернуть функции? –

8

мне удалось получить достойное решение, используя TokenAuthenticator и перехватчик и думал, что я разделяю мысль, как это может помочь некоторым другим.

Добавление класса «TokenInterceptor», который обрабатывает добавление токена в заголовок, является токеном, а класс «TokenAuthenticator» обрабатывает случай, когда нет токена, и нам нужно его создать.

Я уверен, что есть несколько лучших способов реализовать это, но это хорошая отправная точка, я думаю.

public static class TokenAuthenticator implements Authenticator { 
    @Override 
    public Request authenticate(Route route, Response response) throws IOException { 
    ... 
    Session body = call.execute().body(); 
    Logger.d("Session token: " + body.token); 
    // Storing the token somewhere. 
    session.token = body.token; 
    ... 
} 


private static class TokenInterceptor implements Interceptor { 
@Override 
    public Response intercept(Chain chain) throws IOException { 
     Request originalRequest = chain.request(); 

     // Nothing to add to intercepted request if: 
     // a) Authorization value is empty because user is not logged in yet 
     // b) There is already a header with updated Authorization value 
     if (authorizationTokenIsEmpty() || alreadyHasAuthorizationHeader(originalRequest)) { 
      return chain.proceed(originalRequest); 
     } 

     // Add authorization header with updated authorization value to intercepted request 
     Request authorisedRequest = originalRequest.newBuilder() 
       .header("Auth-Token", session.token) 
       .build(); 
     return chain.proceed(authorisedRequest); 
    } 
} 

Источник:

http://lgvalle.xyz/2015/07/27/okhttp-authentication/

Смежные вопросы