2015-06-23 4 views
1

Я столкнулся с довольно простой ситуацией, но я не могу обвести вокруг нее голову. Возможно, гуру OkHttp могли проследить мой путь.Заголовок проверки подлинности и аутентификации в OkHTTP

Я использую Picasso, Retrofit и OkHttp для нескольких целей на моем приложении для Android. ура!. По мере того, как я правильно читаю, разработчик должен прилагать усилия к тому, чтобы поддерживать OkHttpClient (как здесь).

При подходе в виду, я хочу, любой из моих HTTP вызовов (будь то API вызова При загрузке изображения, ресурс загрузки) для:

  1. Отправьте запрос
  2. Если HTTP401 получено , затем Послать другой HTTP-запрос, который отправляет токен обратно
  3. Когда этот токен получен, вызов переизлучается с помощью этого токена, включенного в заголовки
  4. Любой последующий вызов (будь то API, вызов ресурса или изображения) должен использовать этот токен, пока не будет получен следующий HTTP401 (недопустимый токен).

Конечно, я бы повторно использовать тот же клиент для Модернизированный и Пикассо в .

Один маршрут, который я рассматриваю, заключается в использовании смеси Authenticator и приложения Interceptor. Аутентификатор должен улавливать HTTP401, но могу ли я заставить его сделать еще один запрос синхронизации, сохранить токен и активировать новый перехватчик?

ответ

3

Похоже, я нашел решение самостоятельно для этой проблемы, поэтому давайте поделимся знаниями со всеми.

Для этого OkHttp уже предоставляет все необходимые крючки.

  1. Убедиется использовать Authenticator
  2. Установите перехватчик раза аутентикатора успеха
  3. возвращающего запрос с хорошим маркером.

Это также подразумевает, что Authenticator обрабатывает HTTP, чтобы установить маркер обратно (выполняется в другой службе android).

okHttpClient.setAuthenticator(new Authenticator() { 
      @Override 
      public Request authenticate(Proxy proxy, Response response) { 

       AccountManager accountManager = AccountManager.get(context); 
       Account[] accounts = accountManager.getAccountsByType(Authenticator.ACCOUNT_TYPE); 
       // No account, do not even try to authenticate 
       if (accounts.length == 0) { 
        Log.i(TAG, "... But we dont have any account yet, so I will just back off for now."); 
        return null; 
       } 

       Account account = accounts[0]; 

       try { 
        final String mCurrentToken = accountManager.blockingGetAuthToken(account, "", false); 

        // For now, we just re-install blindly an interceptor 
        okHttpClient.interceptors().clear(); 
        Log.i(TAG, "... Installing interceptor after authentication"); 
        okHttpClient.interceptors().add(new Interceptor() { 
          @Override public Response intercept(Chain chain) throws IOException { 
           Request request = chain.request(); 
           Request newReq = request.newBuilder() 
            .addHeader("Authorization", mCurrentToken) 
            .build(); 
           Response response = chain.proceed(newReq); 

           return response; 
          } 
         }); 
        Log.i(TAG, "Install temporary auth token in request"); 
        return response.request().newBuilder() 
         .addHeader("Authorization", mCurrentToken) 
         .build(); 

       } catch (OperationCanceledException e) { 
        Log.e(TAG, "Interrupted exception"); 
        return null; 
       } catch (AuthenticatorException e) { 
        Log.e(TAG, "Authentication error"); 
        return null; 
       } catch (IOException e) { 
        Log.e(TAG, "IO Error"); 
        return null;       
       } 
      } 


      @Override 
      public Request authenticateProxy(Proxy proxy, Response response) { 
       return null; // Null indicates no attempt to authenticate. 
      } 
     }) 

С этим просто используйте этот OkClient в Picasso и Retrofit.

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