Android OkHttp with Basic Authentication

后端 未结 12 1504
感动是毒
感动是毒 2020-12-07 12:58

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 w

相关标签:
12条回答
  • 2020-12-07 13:37

    All answers are good but no one said, that for some requests content-type is required, you should add a content-type to your request like this:

    Request request = new Request.Builder()
            .url(url)
            .addHeader("content-type", "application/json") 
            .post(body)
            .build();
    

    If you don't add it, you will get Unauthorized message and you will waste a lot of time to fix it.

    0 讨论(0)
  • 2020-12-07 13:41

    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();
    
    0 讨论(0)
  • 2020-12-07 13:45

    Someone asked for a Kotlin version of the interceptor. Here is what I came up with and it works great:

            val client = OkHttpClient().newBuilder().addInterceptor { chain ->
            val originalRequest = chain.request()
    
            val builder = originalRequest.newBuilder()
                    .header("Authorization", Credentials.basic("ausername", "apassword"))
            val newRequest = builder.build()
            chain.proceed(newRequest)
        }.build()
    
    0 讨论(0)
  • 2020-12-07 13:46

    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) {
        final String login = "your_login";
        final String password = "p@s$w0rd";
        String credential = Credentials.basic(login, password);
        return request.newBuilder().header("Authorization", credential).build();
    }
    
    0 讨论(0)
  • 2020-12-07 13:47

    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;
      }
    })
    
    0 讨论(0)
  • 2020-12-07 13:47

    In my case it only worked when I integrated authorization into the header (OkHttp Version 4.0.1):

    Request request = new Request.Builder()
        .url("www.url.com/api")
        .addHeader("Authorization", Credentials.basic("username", "password"))
        .build();
    
    Request response = client.newCall(request).execute();
    
    0 讨论(0)
提交回复
热议问题