Android OkHttp with Basic Authentication

后端 未结 12 1505
感动是毒
感动是毒 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:48

    In OkHttp3, you set the authorization on the OkHttpClient itself by adding the authenticator() method. After your original call comes back with the 401 response, the authenticator() adds the Authorization header

     new OkHttpClient.Builder()
            .connectTimeout(10000, TimeUnit.MILLISECONDS)
            .readTimeout(10000, TimeUnit.MILLISECONDS)
            .authenticator(new Authenticator() {
               @Nullable
               @Override
               public Request authenticate(@NonNull Route route, @NonNull Response response) {
                 if (response.request().header(HttpHeaders.AUTHORIZATION) != null)
                   return null;  //if you've tried to authorize and failed, give up
    
                 String credential = Credentials.basic("username", "pass");
                 return response.request().newBuilder().header(HttpHeaders.AUTHORIZATION, credential).build();
              }
            })
            .build();
    

    Although it's more secure, if you don't want to spam the server with all the 401 requests in the first place, you can use something called preauthentication, where you send the Authorization header to begin with on your requests

    String credentials = Credentials.basic("username", "password");
    Request httpRequest = new Request.Builder()
                     .url("some/url")
                     .header("content-type", "application/json") 
                     .header(HttpHeaders.AUTHORIZATION, credentials)
                     .build();
    
    0 讨论(0)
  • 2020-12-07 13:50

    I noticed on Android with some server APIs like django you should add a word in token

    Request request = new Request.Builder()
        .url(theUrl)
        .header("Authorization", "Token 6utt8gglitylhylhlfkghriyiuy4fv76876d68")
        .build();
    

    , where that problematic word is that "Token ". Overall you should carefully see rules of those specific server APIs about how to compose requests.

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

    Try using OkAuthenticator:

    client.setAuthenticator(new OkAuthenticator() {
      @Override public Credential authenticate(
          Proxy proxy, URL url, List<Challenge> challenges) throws IOException {
        return Credential.basic("scott", "tiger");
      }
    
      @Override public Credential authenticateProxy(
          Proxy proxy, URL url, List<Challenge> challenges) throws IOException {
        return null;
      }
    });
    

    UPDATE:

    Renamed to Authenticator

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

    This is a snippet for OkHttp Client:

      OkHttpClient client = new OkHttpClient.Builder()
                   .authenticator(new Authenticator() {
                  @Override public Request authenticate(Route route, Response 
       response) throws IOException {
                       if (response.request().header("Authorization") != null) {
                          return null; // Give up, we've already attempted to 
       authenticate.
                       }
    
                      System.out.println("Authenticating for response: " + response);
                      System.out.println("Challenges: " + response.challenges());
                       String credential = Credentials.basic(username, password);
                       return response.request().newBuilder()
                               .header("Authorization", credential)
                               .build();
                   }
               }) .build(); 
    

    Do a request now. Basic auth will go as client already has that.

        Request request = new Request.Builder().url(JIRAURI+"/issue/"+key).build();
                    client.newCall(request).enqueue(new Callback() {
                        @Override
                       public void onFailure(Call call, IOException e) {
                           System.out.println("onFailure: "+e.toString());
                        }
    
                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        System.out.println( "onResponse: "+response.body().string());
    
                    }
                });
    
    0 讨论(0)
  • 2020-12-07 13:58

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

    Okhttp3 with base 64 auth

    String endpoint = "https://www.example.com/m/auth/"
    String username = "user123";
    String password = "12345";
    String credentials = username + ":" + password;
    
    final String basic =
            "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
    Request request = new Request.Builder()
            .url(endpoint)
            .header("Authorization", basic)
            .build();
    
    
    OkHttpClient client = SomeUtilFactoryClass.buildOkhttpClient();
    client.newCall(request).enqueue(new Callback() {
    ...
    
    0 讨论(0)
提交回复
热议问题