Retrofit自定義攔截器校驗登入是否過期
每一個應用基本都需要登入功能,具體我就不說了。那麼後臺伺服器登入過期一般是通過校驗Session是否過期來判斷的。因此在我們請求伺服器時候的時候,每次都需要把sessionId傳到後臺伺服器,後臺通過sessionId判斷登入是否過期,然後返回對應的code,Android客戶端通過該code判斷登入是否過期。而sessionId怎麼傳到後臺伺服器也是很多人不瞭解的。sessionId其實是在請求頭中,在Android中通過Set-Cookie可以拿到。
下面我們介紹Retrofit通過自定義攔截器校驗登入是否過期。
1.首次請求的時候,把sessionId存到本地
package com.mujin.keji.collectionsystem.interceptor; import com.alibaba.fastjson.JSONObject; import com.mujin.keji.collectionsystem.Constant; import com.mujin.keji.collectionsystem.utils.SPUtil; import java.io.IOException; import java.util.ArrayList; import java.util.List; import okhttp3.Interceptor; import okhttp3.Response; /** * 首次請求的處理 * @author : weishixiong * @create : 18/05/03 */ public class ReceivedCookiesInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Response originalResponse = chain.proceed(chain.request()); if (!originalResponse.headers("Set-Cookie").isEmpty()) { List<String> cookies = new ArrayList<>(); for (String header : originalResponse.headers("Set-Cookie")) { cookies.add(header); } String cookieStr = JSONObject.toJSONString(cookies); SPUtil.putData(Constant.SP.SP, Constant.SP.SESSION_ID, cookieStr); } return originalResponse; } }
2.非首次請求的時候把存在本地的sessionId放到請求頭,傳到後臺,後臺伺服器通過該sessionId判斷登入是否過期
package com.mujin.keji.collectionsystem.interceptor; import android.util.Log; import com.alibaba.fastjson.JSONObject; import com.mujin.keji.collectionsystem.Constant; import com.mujin.keji.collectionsystem.utils.SPUtil; import java.io.IOException; import java.util.List; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; /** * 非首次請求的處理 * @author : weishixiong * @create : 18/05/03 */ public class AddCookiesInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request.Builder builder = chain.request().newBuilder(); String cookieStr = SPUtil.getData(Constant.SP.SP, Constant.SP.SESSION_ID, String.class, null); List<String> cookies = JSONObject.parseArray(cookieStr, String.class); if (cookies != null) { for (String cookie : cookies) { builder.addHeader("Cookie", cookie); Log.v("OkHttp", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp } } return chain.proceed(builder.build()); } }
3.如果登入過期,或者退出登入之後,記得清除本地的sessionId
/** * 退出登入 */ private static void out(String msg) { SPUtil.clearData(Constant.SP.SP); }
4.設定攔截器
/** * 建立okhttp相關物件 */ okHttpClient = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) {//訪問網路請求,和服務端響應請求時。將資料攔截並輸出 Log.e(TAG, "log: " + message); } }).setLevel(HttpLoggingInterceptor.Level.BODY))//Log等級 .connectTimeout(Constant.Server.TIME_OUT, TimeUnit.SECONDS)//超時時間 .readTimeout(Constant.Server.TIME_OUT, TimeUnit.SECONDS) .writeTimeout(Constant.Server.TIME_OUT, TimeUnit.SECONDS) .addNetworkInterceptor(new StethoInterceptor()) .addInterceptor(new AddCookiesInterceptor()) //首次請求 .addInterceptor(new ReceivedCookiesInterceptor()) //非首次請求 .hostnameVerifier(new SafeHostnameVerifier()) .sslSocketFactory(CcsApplication.getSslSocket(),new SafeTrustManager ()) // .build();