Retrofit 通過重新整理頭部Token解決token過期
阿新 • • 發佈:2018-12-18
需求分析:
現在大多數應用也都有使用token來維持使用者登陸狀態,但後臺設定的token也都是有一定期限的,那麼不可避免的我們的Android應用會存在token過期的問題,那麼下面我們就來研究token過期的問題,來達到token失敗再次獲取token拿取資料的目的。
執行結果:
闡述,首先是驗證了token過去,然後去獲得token緊接著再去獲取資源資訊,即成功獲取最終的資料。
核心程式碼,也都有註釋。這裡說明一點,獲取token一定得是同步請求,非同步會造成在請求完前進行返回。
public class MyBaseApiRetrofit { private final OkHttpClient mClient; // 這裡的token是從資料庫中獲得的------------- private String token = "Bearer default"; public OkHttpClient getClient() { return mClient; } public MyBaseApiRetrofit(){ //OkHttpClient OkHttpClient.Builder builder = new OkHttpClient.Builder(); // -------- 在這裡獲得 token,通過資料庫快取 ********----------- if (BuildConfig.DEBUG) { // Log資訊攔截器 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); //設定 Debug Log 模式 builder.addInterceptor(loggingInterceptor); } // 新增頭部攔截器 並設定驗證重新整理 ******* builder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request.Builder request = chain.request().newBuilder(); //新增Token請求頭 這裡的token應當是從本地資料庫中讀取的 ********** request.addHeader("Authorization", token); Response proceed = chain.proceed(request.build()); //如果token過期 再去重新請求token 然後設定token的請求頭 重新發起請求 使用者無感 if (isTokenExpired(proceed)){ String newHeaderToken = getNewToken(); //使用新的Token,建立新的請求 Request newRequest = chain.request().newBuilder() .addHeader("Authorization", newHeaderToken) .build(); return chain.proceed(newRequest); } return proceed; } }); mClient = builder.build(); } /** * 根據Response,判斷Token是否失效 * 401表示token過期 * @param response * @return */ private boolean isTokenExpired(Response response) { Log.e("狀態碼",response.code()+"---------------------"); if (response.code() == 401) { return true; } return false; } /** * 這裡可以考慮讓後臺提供一個介面,通過使用者名稱直接返回一個token----------------- * @return * @throws IOException */ @SuppressLint("CheckResult") private String getNewToken() throws IOException { LoginRequest loginRequest = new LoginRequest(); loginRequest.setUsername("apple2"); loginRequest.setPassword("123abc"); OkHttpClient okHttpClient = new OkHttpClient(); Gson gson = new Gson(); String json = gson.toJson(loginRequest); RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8") , json); Request request = new Request.Builder().url(MyApi.BASE_URL+"auth").post(requestBody).build(); Call call = okHttpClient.newCall(request); String string = Objects.requireNonNull(call.execute().body()).string(); MyLoginResponse loginResponse = JsonUtils.jsonToBean(string, MyLoginResponse.class); token = "Bearer "+loginResponse.getData().getToken(); Log.e("token重新整理結果",token); return token; } }