Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android OkHttp with Basic Authentication

Tags:

android

okhttp

I'm using the OkHttp library for a new project and am impressed with its ease of use. I now have a need to use Basic Authentication. Unfortunately, there is a dearth of working sample code. I'm seeking an example of how to pass username / password credentials to the OkAuthenticator when an HTTP 401 header is encountered. I viewed this answer:

Retrofit POST request w/ Basic HTTP Authentication: "Cannot retry streamed HTTP body"

but it didn't get me too far. The samples on the OkHttp github repo didn't feature an authentication-based sample either. Does anyone have a gist or other code sample to get me pointed in the right direction? Thanks for your assistance!

like image 593
Kerr Avatar asked Mar 18 '14 20:03

Kerr


People also ask

Does Android use OkHttp?

okhttp , artifactId, okhttp and the version 2.5. 0 (current as of this writing). As of Android 5.0, OkHttp is part of the Android platform and is used for all HTTP calls.

What is OkHttp client in Android?

OkHttp android provides an implementation of HttpURLConnection and Apache Client interfaces by working directly on a top of java Socket without using any extra dependencies.

What is interceptor in OkHttp?

Interceptors, according to the documentation, are a powerful mechanism that can monitor, rewrite, and retry the API call. So, when we make an API call, we can either monitor it or perform some tasks. In a nutshell, Interceptors function similarly to airport security personnel during the security check process.

What is the underlying library of OkHttp?

Beginning with Mobile SDK 4.2, the Android REST request system uses OkHttp (v3. 2.0), an open-source external library from Square Open Source, as its underlying architecture. This library replaces the Google Volley library from past releases.


2 Answers

Update Code for okhttp3:

import okhttp3.Authenticator; import okhttp3.Credentials; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.Route;  public class NetworkUtil {  private final OkHttpClient.Builder client;  {     client = new OkHttpClient.Builder();     client.authenticator(new Authenticator() {         @Override         public Request authenticate(Route route, Response response) throws IOException {             if (responseCount(response) >= 3) {                 return null; // If we've failed 3 times, give up. - in real life, never give up!!             }             String credential = Credentials.basic("name", "password");             return response.request().newBuilder().header("Authorization", credential).build();         }     });     client.connectTimeout(10, TimeUnit.SECONDS);     client.writeTimeout(10, TimeUnit.SECONDS);     client.readTimeout(30, TimeUnit.SECONDS); }  private int responseCount(Response response) {     int result = 1;     while ((response = response.priorResponse()) != null) {         result++;     }     return result; }  } 
like image 117
nuss Avatar answered Oct 16 '22 01:10

nuss


As pointed out by @agamov:

The aforementioned solution has one drawback: httpClient adds authorization headers only after receiving 401 response

@agamov proposed then to "manually" add authentication headers to each request, but there is a better solution: use an Interceptor:

import java.io.IOException; import okhttp3.Credentials; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response;  public class BasicAuthInterceptor implements Interceptor {      private String credentials;      public BasicAuthInterceptor(String user, String password) {         this.credentials = Credentials.basic(user, password);     }      @Override     public Response intercept(Chain chain) throws IOException {         Request request = chain.request();         Request authenticatedRequest = request.newBuilder()                     .header("Authorization", credentials).build();         return chain.proceed(authenticatedRequest);     }  } 

Then, simply add the interceptor to an OkHttp client that you will be using to make all your authenticated requests:

OkHttpClient client = new OkHttpClient.Builder()     .addInterceptor(new BasicAuthInterceptor(username, password))     .build(); 
like image 38
Alphaaa Avatar answered Oct 16 '22 02:10

Alphaaa