前面介紹了kotlin之RxJava2+Retrofit2邮旷,現(xiàn)在就部分項目中遇到的Token刷新問題做個思路。
Token是指個別項目中引入的請求令牌蝇摸,在首次登陸后會得到一個隨機字符串婶肩,這個隨機字符串有一定的時間限制,過期后需要使用特定的字符串去刷新這個token以保證后續(xù)的接口能夠正常訪問貌夕。
這里有兩種解決方案律歼,一種是使用okhttp提供Authenticator類,這種方式只適用于服務器將鑒權(quán)失敗以狀態(tài)碼的方式返回啡专。另一種就是添加攔截器险毁,適用于認定鑒權(quán)失敗時正常的業(yè)務請求,返回狀態(tài)碼依然是200们童。
方案一
先上干貨
class TokenAuthenticator : Authenticator {
override fun authenticate(route: Route?, response: Response?): Request? {
val refreshToken = Utils.defaultSP.getString(Constants.KEY_REFRESH_TOKEN, null)
var newToken: String? = null
//這里使用同步的方式去獲取新的token
if (refreshToken != null) newToken = ApiService.default().refreshToken(refreshToken).execute().body()
return if (newToken != null) {
Utils.defaultSP.edit().putString(Constants.KEY_ACCESS_TOKEN, newToken).apply()
response?.request()?.newBuilder()?.header("Authentication", newToken)?.build()
} else {
response?.request()
}
}
}
okHttpBuilder.authenticator(authenticator)
覆寫Authenticator 類后畔况,并在構(gòu)建okhttpclient的時候可以添加進去。在網(wǎng)絡請求返回后如果狀態(tài)碼是401則會回調(diào)authenticate方法慧库,在這個方法中我們需要做的就是利用refresh_token字符串去獲取新的Token跷跪。如果拿到了新的token則將新的token替換到原本請求頭中的字段再發(fā)起一次請求,如果沒有拿到新的token則返回原來的請求齐板。
方案二
class TokenInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain?): Response {
val originalRequest = chain?.request()
val response = chain?.proceed(originalRequest)
val json = response?.body().toString()
if (!TextUtils.isEmpty(json)) {
val obj = JSONObject(json)
if (obj.has("code") && obj.getInt("code") == Constants.NET_CODE_TOKEN_EXPIRE) {
val refreshToken = Utils.defaultSP.getString(Constants.KEY_REFRESH_TOKEN, null)
var newToken: String? = null
if (refreshToken != null) newToken = ApiService.default().refreshToken(refreshToken).execute().body()
if (newToken != null) {
Utils.defaultSP.edit().putString(Constants.KEY_ACCESS_TOKEN, newToken).apply()
val requestBuilder = originalRequest?.newBuilder()?.header("Authentication", newToken)
return chain!!.proceed(requestBuilder?.build())
}
}
}
return response!!
}
}
okHttpBuilder.addInterceptor(interceptor)
以上是使用攔截器的方式來監(jiān)聽網(wǎng)絡請求的結(jié)果吵瞻,判斷業(yè)務碼是某個值時發(fā)起刷新Token的網(wǎng)絡請求葛菇,順利拿到新的token后替換掉原來請求頭的字段,并再次發(fā)起請求橡羞。
總結(jié)
以上是目前認為比較簡單的處理刷新token的方式眯停,個人更推薦第二種方式一點,但也要結(jié)合實際的需求卿泽,如果有更好的方式莺债,可以和我探討我在補充出來分享給大家。