更新 token 刷新

新增 token 刷新功能,包括 API 接口和拦截器逻辑。
This commit is contained in:
2024-08-31 23:49:15 +08:00
parent 98430f3282
commit 091926a3c1
6 changed files with 66 additions and 25 deletions

View File

@@ -4,6 +4,9 @@ import android.icu.text.SimpleDateFormat
import android.icu.util.TimeZone
import com.aiosman.riderpro.AppStore
import com.aiosman.riderpro.ConstVars
import com.aiosman.riderpro.data.ServiceException
import com.auth0.android.jwt.JWT
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
@@ -16,7 +19,9 @@ import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
fun getUnsafeOkHttpClient(): OkHttpClient {
fun getUnsafeOkHttpClient(
authInterceptor: AuthInterceptor? = null
): OkHttpClient {
return try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
@@ -46,7 +51,11 @@ fun getUnsafeOkHttpClient(): OkHttpClient {
OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
.hostnameVerifier { _, _ -> true }
.addInterceptor(AuthInterceptor())
.apply {
authInterceptor?.let {
addInterceptor(it)
}
}
.build()
} catch (e: Exception) {
throw RuntimeException(e)
@@ -56,8 +65,42 @@ fun getUnsafeOkHttpClient(): OkHttpClient {
class AuthInterceptor() : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val requestBuilder = chain.request().newBuilder()
val token = AppStore.token
token?.let {
val jwt = JWT(token)
val expiresAt = jwt.expiresAt?.time?.minus(3000)
val currentTime = System.currentTimeMillis()
val isExpired = expiresAt != null && currentTime > expiresAt
if (isExpired) {
runBlocking {
val newToken = refreshToken()
if (newToken != null) {
AppStore.token = newToken
}
}
}
}
requestBuilder.addHeader("Authorization", "Bearer ${AppStore.token}")
return chain.proceed(requestBuilder.build())
val response = chain.proceed(requestBuilder.build())
return response
}
private suspend fun refreshToken(): String? {
val client = Retrofit.Builder()
.baseUrl(ApiClient.RETROFIT_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(getUnsafeOkHttpClient())
.build()
.create(RiderProAPI::class.java)
val resp = client.refreshToken(AppStore.token ?: "")
val newToken = resp.body()?.token
if (newToken != null) {
AppStore.token = newToken
}
return newToken
}
}
@@ -67,7 +110,7 @@ object ApiClient {
const val RETROFIT_URL = "${BASE_API_URL}/"
const val TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"
private val okHttpClient: OkHttpClient by lazy {
getUnsafeOkHttpClient()
getUnsafeOkHttpClient(authInterceptor = AuthInterceptor())
}
private val retrofit: Retrofit by lazy {
Retrofit.Builder()

View File

@@ -89,6 +89,11 @@ interface RiderProAPI {
@GET("auth/token")
suspend fun checkToken(): Response<ValidateTokenResult>
@GET("auth/refresh_token")
suspend fun refreshToken(
@Query("token") token: String
): Response<AuthResult>
@GET("posts")
suspend fun getPosts(
@Query("page") page: Int = 1,