OkHttp implements automatic refresh of globally expired token s

Keywords: Android network Retrofit OkHttp

#Problem encountered:

App currently being developed has a problem:

When an interface is requested, it will fail because the token is no longer valid.
However, the product manager expects the app to refresh the token immediately and then repeat the request for the interface, which is insensitive to the user.
>
This means silent automatic login and then continue requesting:
>
Request Interface A -> Server returns token expiration -> Request token refresh interface -> Request interface A
>
How will people achieve these needs?

#Solution:

Ideas:
1. Get the returned data through the interceptor
2. Determine whether token expires
3. Refresh token if token expires
4. Re-request network data using the latest token

 1 /**
 2  * Interceptor for global automatic refresh of Token
 3  */
 4 public class TokenInterceptor implements Interceptor {
 5 
 6     @Override
 7     public Response intercept(Chain chain) throws IOException {
 8         Request request = chain.request();
 9         Response response = chain.proceed(request);
10         LogUtil.print("response.code=" + response.code());
11 
12         if (isTokenExpired(response)) {//Judging by agreement with the server token Be overdue
13             LogUtil.print("Silent automatic refresh Token,Then re-request the data");
14             //Synchronize requests to get the latest Token
15             String newSession = getNewToken();
16             //Use New Token,Create a new request
17             Request newRequest = chain.request()
18                     .newBuilder()
19                     .header("Cookie", "JSESSIONID=" + newSession)
20                     .build();
21             //Re-request
22             return chain.proceed(newRequest);
23         }
24         return response;
25     }
26 
27     /**
28      * Determine whether Token is invalid based on Response
29      *
30      * @param response
31      * @return
32      */
33     private boolean isTokenExpired(Response response) {
34         if (response.code() == 404) {
35             return true;
36         }
37         return false;
38     }
39 
40     /**
41      * Synchronize requests to get the latest Token
42      *
43      * @return
44      */
45     private String getNewToken() throws IOException {
46         // Get new through a specific interface token,Synchronized is used here retrofit request
47         Response_Login loginInfo = CacheManager.restoreLoginInfo(BaseApplication.getContext());
48         String username = loginInfo.getUserName();
49         String password = loginInfo.getPassword();
50 
51         LogUtil.print("loginInfo=" + loginInfo.toString());
52         Call<Response_Login> call = WebHelper.getSyncInterface().synclogin(new Request_Login(username, password));
53         loginInfo = call.execute().body();
54         LogUtil.print("loginInfo=" + loginInfo.toString());
55 
56         loginInfo.setPassword(password);
57         CacheManager.saveLoginInfo(loginInfo);
58         return loginInfo.getSession();
59     }
60 }

Then configure OkHttp

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(300, TimeUnit.SECONDS)
                .writeTimeout(300, TimeUnit.SECONDS)
                .cache(new Cache(FileConstants.HTTP_CACHE_DIR, FileConstants.CACHE_SIZE))
                .addInterceptor(interceptor)
//                .addInterceptor(new MockInterceptor())
                .addInterceptor(new TokenInterceptor())
//                .addInterceptor(new RetryIntercepter(3))
                .addInterceptor(logging)
                .build();

Posted by timandkitty on Tue, 28 Apr 2020 09:59:38 -0700