Android Okhttp With Basic Authentication
Solution 1:
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;
publicclassNetworkUtil {
privatefinal OkHttpClient.Builder client;
{
client = newOkHttpClient.Builder();
client.authenticator(newAuthenticator() {
@Overridepublic Request authenticate(Route route, Response response)throws IOException {
if (responseCount(response) >= 3) {
returnnull; // If we've failed 3 times, give up. - in real life, never give up!!
}
Stringcredential= 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);
}
privateintresponseCount(Response response) {
intresult=1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
}
Solution 2:
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;
publicclassBasicAuthInterceptorimplementsInterceptor {
private String credentials;
publicBasicAuthInterceptor(String user, String password) {
this.credentials = Credentials.basic(user, password);
}
@Overridepublic Response intercept(Chain chain)throws IOException {
Requestrequest= chain.request();
RequestauthenticatedRequest= 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:
OkHttpClientclient=newOkHttpClient.Builder()
.addInterceptor(newBasicAuthInterceptor(username, password))
.build();
Solution 3:
Here's the updated code:
client.setAuthenticator(newAuthenticator() {
@Overridepublic Request authenticate(Proxy proxy, Response response)throws IOException {
Stringcredential= Credentials.basic("scott", "tiger");
return response.request().newBuilder().header("Authorization", credential).build();
}
@Overridepublic Request authenticateProxy(Proxy proxy, Response response)throws IOException {
returnnull;
}
})
Solution 4:
Try using OkAuthenticator:
client.setAuthenticator(newOkAuthenticator() {
@Overridepublic Credential authenticate(
Proxy proxy, URL url, List<Challenge> challenges)throws IOException {
return Credential.basic("scott", "tiger");
}
@Overridepublic Credential authenticateProxy(
Proxy proxy, URL url, List<Challenge> challenges)throws IOException {
returnnull;
}
});
UPDATE:
Renamed to Authenticator
Solution 5:
The aforementioned solution has one drawback:
httpClient adds authorization headers only after receiving 401 response.
Here's how my communication with api-server looked like:
If you need to use basic-auth for every request, better add your auth-headers to each request or use a wrapper method like this:
private Request addBasicAuthHeaders(Request request) {
finalStringlogin="your_login";
finalStringpassword="p@s$w0rd";
Stringcredential= Credentials.basic(login, password);
return request.newBuilder().header("Authorization", credential).build();
}
Post a Comment for "Android Okhttp With Basic Authentication"