android – OkHttp和Retrofit,用并发请求刷新令牌

前端之家收集整理的这篇文章主要介绍了android – OkHttp和Retrofit,用并发请求刷新令牌前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的应用程序中,我实现了Retrofit来调用WebServices,我使用OkHttp来使用Interceptor和Authenticator.有些请求需要 token,我已经实现了Authenticator接口来处理刷新(遵循官方 documentation).但我有以下问题:在我的应用程序中不时,我必须立即调用多个请求.因此,对于其中一个我将有401错误.

这是我的请求调用代码

public static <S> S createServiceAuthentication(Class<S> serviceClass,boolean hasPagination) {

        final String jwt = JWT.getJWTValue(); //Get jwt value from Realm

        if (hasPagination) {
            Gson gson = new GsonBuilder().
                    registerTypeAdapter(Pagination.class,new PaginationTypeAdapter()).create();

            builder =
                    new Retrofit.Builder()
                            .baseUrl(APIConstant.API_URL)
                            .addConverterFactory(GsonConverterFactory.create(gson));
        }

        OkHttpClient.Builder httpClient =
                new OkHttpClient.Builder();

        httpClient.addInterceptor(new AuthenticationInterceptor(jwt));
        httpClient.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route,Response response) throws IOException {
                if (responseCount(response) >= 2) {
                    // If both the original call and the call with refreshed token Failed,// it will probably keep failing,so don't try again.
                    return null;
                }

                if (jwt.equals(response.request().header("Authorization"))) {
                    return null; // If we already Failed with these credentials,don't retry.
                }

                APIRest apiRest = createService(APIRest.class,false);
                Call<JWTResponse> call = apiRest.refreshToken(new JWTBody(jwt));
                try {
                    retrofit2.Response<JWTResponse> refreshTokenResponse = call.execute();
                    if (refreshTokenResponse.isSuccessful()) {

                        JWT.storeJwt(refreshTokenResponse.body().getJwt());

                        return response.request().newBuilder()
                                .header(CONTENT_TYPE,APPLICATION_JSON)
                                .header(ACCEPT,APPLICATION)
                                .header(AUTHORIZATION,"Bearer " + refreshTokenResponse.body().getJwt())
                                .build();
                    } else {
                        return null;
                    }
                } catch (IOException e) {
                    return null;
                }
            }
        });

        builder.client(httpClient.build());
        retrofit = builder.build();

        return retrofit.create(serviceClass);
    }

    private static int responseCount(Response response) {
        int result = 1;
        while ((response = response.priorResponse()) != null) {
            result++;
        }
        return result;
    }

问题很简单,第一个请求将成功刷新令牌,但其他请求将失败,因为他们将尝试刷新已刷新的令牌. WebService返回错误500.有没有优雅的解决方案来避免这种情况?

谢谢 !

解决方法

如果我了解您的问题,则在更新令牌时会发送一些请求,这会给您一个错误.

您可以尝试在更新令牌时使用“同步”对象来阻止所有请求,但这不会涵盖已发送请求的情况.

由于这个问题很难完全避免,这里的正确方法可能是有一个良好的后备行为.处理在令牌更新期间发出请求时获得的错误,例如通过使用更新的令牌重新运行请求.

猜你在找的Android相关文章