在Okhttp中处理身份验证

时间:2015-04-05 10:53:55

标签: android authentication http-status-code-401 okhttp okio

我使用OkHttp 2.3进行基本身份验证请求,根据OKHttp文档,它会自动重试未经身份验证的请求,但每当我提供无效凭据时,请求都会花费太多时间,我会在端:

  

java.net.ProtocolException:后续请求太多:21

如何阻止OkHttp自动重试未经身份验证的请求,并返回401 Unauthorized

2 个答案:

答案 0 :(得分:13)

protected Authenticator getBasicAuth(final String username, final String password) {
    return new Authenticator() {
        private int mCounter = 0;

        @Override
        public Request authenticate(Proxy proxy, Response response) throws IOException {
            if (mCounter++ > 0) {
                throw new AuthenticationException(
                        AuthenticationException.Type.INVALID_LOGIN, response.message());
            }

            String credential = Credentials.basic(username, password);
            return response.request().newBuilder().header("Authorization", credential).build();
        }

        @Override
        public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
            return null;
        }
    };
}

在我的身份验证器中,我只计算尝试次数 - 在X次尝试之后,我抛出异常。

答案 1 :(得分:1)

Traxdata的修改版本的答案有效:

protected Authenticator getBasicAuth(final String username, final String password) {
    return new Authenticator() {
        private int mCounter = 0;

        @Override
        public Request authenticate(Route route, Response response) throws IOException {
            Log.d("OkHttp", "authenticate(Route route, Response response) | mCounter = " + mCounter);
            if (mCounter++ > 0) {
                Log.d("OkHttp", "authenticate(Route route, Response response) | I'll return null");
                return null;
            } else {
                Log.d("OkHttp", "authenticate(Route route, Response response) | This is first time, I'll try to authenticate");
                String credential = Credentials.basic(username, password);
                return response.request().newBuilder().header("Authorization", credential).build();
            }
        }
    };
}

然后你需要:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.authenticator(getBasicAuth("username", "pass"));
retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(builder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

那就是它。