更新 token 刷新
新增 token 刷新功能,包括 API 接口和拦截器逻辑。
This commit is contained in:
@@ -90,5 +90,6 @@ dependencies {
|
||||
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
|
||||
implementation("androidx.credentials:credentials:1.2.2")
|
||||
implementation("androidx.credentials:credentials-play-services-auth:1.2.2")
|
||||
implementation("com.auth0.android:jwtdecode:2.0.2")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.aiosman.riderpro
|
||||
|
||||
object ConstVars {
|
||||
// api 地址
|
||||
// const val BASE_SERVER = "http://192.168.31.250:8088"
|
||||
// const val BASE_SERVER = "http://192.168.31.190:8088"
|
||||
// const val BASE_SERVER = "http://192.168.31.251:8088"
|
||||
const val BASE_SERVER = "https://8.137.22.101:8088"
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -56,15 +56,15 @@ fun CustomAsyncImage(
|
||||
contentScale: ContentScale = ContentScale.Crop
|
||||
) {
|
||||
val imageLoader = getImageLoader(context)
|
||||
val blurBitmap = remember(blurHash) {
|
||||
blurHash?.let {
|
||||
BlurHashDecoder.decode(
|
||||
blurHash = it,
|
||||
width = DEFAULT_HASHED_BITMAP_WIDTH,
|
||||
height = DEFAULT_HASHED_BITMAP_HEIGHT
|
||||
)
|
||||
}
|
||||
}
|
||||
// val blurBitmap = remember(blurHash) {
|
||||
// blurHash?.let {
|
||||
// BlurHashDecoder.decode(
|
||||
// blurHash = it,
|
||||
// width = DEFAULT_HASHED_BITMAP_WIDTH,
|
||||
// height = DEFAULT_HASHED_BITMAP_HEIGHT
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
// var bitmap by remember(imageUrl) { mutableStateOf<Bitmap?>(null) }
|
||||
//
|
||||
@@ -86,16 +86,6 @@ fun CustomAsyncImage(
|
||||
model = ImageRequest.Builder(context)
|
||||
.data(imageUrl)
|
||||
.crossfade(200)
|
||||
.apply {
|
||||
if (placeholderRes != null) {
|
||||
placeholder(placeholderRes)
|
||||
return@apply
|
||||
}
|
||||
if (blurBitmap != null) {
|
||||
placeholder(blurBitmap.toDrawable(context.resources))
|
||||
}
|
||||
|
||||
}
|
||||
.build(),
|
||||
contentDescription = contentDescription,
|
||||
modifier = modifier,
|
||||
|
||||
@@ -5,6 +5,7 @@ import coil.ImageLoader
|
||||
import coil.disk.DiskCache
|
||||
import coil.memory.MemoryCache
|
||||
import coil.request.CachePolicy
|
||||
import com.aiosman.riderpro.data.api.AuthInterceptor
|
||||
import com.aiosman.riderpro.data.api.getUnsafeOkHttpClient
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -18,7 +19,7 @@ object Utils {
|
||||
}
|
||||
|
||||
fun getImageLoader(context: Context): ImageLoader {
|
||||
val okHttpClient = getUnsafeOkHttpClient()
|
||||
val okHttpClient = getUnsafeOkHttpClient(authInterceptor = AuthInterceptor())
|
||||
return ImageLoader.Builder(context)
|
||||
.okHttpClient(okHttpClient)
|
||||
.memoryCachePolicy(CachePolicy.ENABLED)
|
||||
|
||||
Reference in New Issue
Block a user