首页 文章

在Retrofit并行网络调用中处理后台刷新令牌调用

提问于
浏览
1

我是android编程和Retrofit的新手,我正在制作一个示例应用程序,我必须使用访问令牌进行两个并行网络调用 . 当访问令牌过期并返回401状态代码时出现问题,如果我看到401 HTTP状态代码我必须使用此访问令牌调用刷新令牌,但并行调用的问题是它会导致竞争条件以刷新刷新令牌,有没有最好的方法来避免这种情况,以及如何智能刷新令牌没有任何冲突 .

2 回答

  • 2

    当响应是 401 Not Authorized重试上次失败的请求时,OkHttp将自动向 Authenticator 询问凭据 .

    public class TokenAuthenticator implements Authenticator {
        @Override
        public Request authenticate(Proxy proxy, Response response) throws IOException {
            // Refresh your access_token using a synchronous api request
            newAccessToken = service.refreshToken();
    
            // Add new header to rejected request and retry it
            return response.request().newBuilder()
                .header(AUTHORIZATION, newAccessToken)
                .build();
        }
    
        @Override
        public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
            // Null indicates no attempt to authenticate.
            return null;
        }
    

    使用与拦截器相同的方式将 Authenticator 附加到 OkHttpClient

    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.setAuthenticator(authAuthenticator);
    

    在创建Retrofit RestAdapter时使用此客户端

    RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(ENDPOINT)
                .setClient(new OkClient(okHttpClient))
                .build();
    return restAdapter.create(API.class);
    

    检查一下:Fore more details visit this link

  • 0

    尝试为刷新令牌操作创建队列,如:

    class TokenProcessor {
        private List<Listener> queue = new List<Listener>();
        private final Object synch = new Object();
        private State state = State.None;
        private String token;
        private long tokenExpirationDate;
    
        public void getNewToken(Listener listener){
            synchronized(synch) {
    
                // check token expiration date
                if (isTokenValid()){
                    listener.onSuccess(token);
                    return;
                }
                queue.add(listener);
    
                if (state != State.Working) {
                    sendRefreshTokenRequest();
                }
            }
        }
        private void sendRefreshTokenRequest(){
            // get token from your API using Retrofit
            // on the response call onRefreshTokenLoaded() method with the token and expiration date
        }
        private void onRefreshTokenLoaded(String token, long expirationDate){
            synchronized(synch){
                this.token = token;
                this.tokenExpirationDate = expirationDate;
    
                for(Listener listener : queue){
                     try {
                       listener.onTokenRefreshed(token);
                     } catch (Throwable){}
                }
                queue.clear();                
            }
        }
    }
    

    这是一个示例代码,它是如何实现的 .

相关问题