Android OkHttp with Basic Authentication Android OkHttp with Basic Authentication android android

Android OkHttp with Basic Authentication


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;}}


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();


Here's the updated code:

client.setAuthenticator(new Authenticator() {  @Override  public Request authenticate(Proxy proxy, Response response) throws IOException {    String credential = Credentials.basic("scott", "tiger");    return response.request().newBuilder().header("Authorization", credential).build();  }  @Override  public Request authenticateProxy(Proxy proxy, Response response) throws IOException {    return null;  }})