使用侦听器和身份验证器在令牌过期时创建刷新令牌机制

Creating refresh token mechanism when token is expired using interceptor and authenticator

提问人:Nadeem 提问时间:11/10/2023 更新时间:11/10/2023 访问量:19

问:

我想在我的改造请求中创建一个刷新令牌机制,所以如果令牌过期了,我 可以刷新它并调用我使用的 Hilt 依赖注入和改造的相同请求 客户端,当我第一次单击请求时,它正在获取令牌,但我需要再次单击才能使用 我想要相同的点击来做这一切的令牌是我的模块

@Singleton
@Provides
fun providesRetrofitClient(dataStore: DataStore<Preferences>,tokenManager: TokenManager): 
AcademicApi {

    val mHttpLoggingInterceptor = HttpLoggingInterceptor()
        .setLevel(HttpLoggingInterceptor.Level.BODY)
    val mOkHttpClient = OkHttpClient
        .Builder()
        .addInterceptor(mHttpLoggingInterceptor)
        .addInterceptor(AuthInterceptorImpl(tokenManager))
        .authenticator(Authenticate(tokenManager))

        .build()
    return Retrofit.Builder()
        .baseUrl(ACADEMIC_BASE)
        .addConverterFactory(GsonConverterFactory.create(NetworkUtils.gson))
        .client(mOkHttpClient)
        .build()
        .create(AcademicApi::class.java)


}

这是我的令牌管理器代码

 class TokenManager @Inject constructor(private val dataStore: DataStore<Preferences>,
                                   private val tokenRepository: TokenRepository){
val username = stringPreferencesKey("username")
val password = stringPreferencesKey("password")
val authToken = stringPreferencesKey("authToken")
val authenticationToken  = mutableStateOf("")
private val _getToken = MutableStateFlow<GetToken?>(null)
val getToken: StateFlow<GetToken?> get() = _getToken
val usernameFlow: Flow<String> = dataStore.data
    .map { preferences ->
        preferences[username] ?: ""
    }
@Inject
lateinit var authViewModel: AuthViewModel
val passwordFlow: Flow<String> = dataStore.data
    .map { preferences ->
        preferences[password] ?: ""
    }
val authTokenFlow: Flow<String> = dataStore.data
    .map { preferences ->
        preferences[authToken] ?: ""
    }
val combinedFlow: Flow<Pair<String, String>> = usernameFlow.combine(passwordFlow) { 
 username, password ->
    Pair(username, password)
}





suspend fun saveToken(token: GetToken?) {

        val responseData = token

        _getToken.emit(responseData)
        dataStore.edit { settings ->
            settings[authToken] = "Bearer ${responseData?.token.toString()}"
        }




}




// Remove the token (e.g., on logout)
suspend fun clearToken() {
    dataStore.edit { preferences ->
        preferences.remove(authToken)
    }
}

// Token refresh logic (you should implement this)
suspend fun refreshToken() {

    combinedFlow.collect{ (username,password) ->
        val loginRequest = LoginRequest(username,password)
        val flow  = tokenRepository.getAuthToken(loginRequest)

        flow.onCompletion { cause ->
                if (cause != null) {
                    // Handle network errors here*****
                }
            }
            .catch { exception ->
                // Handle exceptions here*****
            }
            .collect { response ->
               saveToken(response.data)

                // Handle the successful response here


            }
    }


}





fun getAccessToken(): Flow<String?> {
    return dataStore.data.map { preferences ->
        preferences[authToken].toString()
    }
}

 }

这是我的拦截器代码

   class AuthInterceptorImpl @Inject constructor(
private val tokenManager: TokenManager
) : Interceptor {



        override fun intercept(chain: Interceptor.Chain): Response {

            val originalRequest = chain.request()
           val acceToken = runBlocking {
               tokenManager.getAccessToken().first()
            }
             val authorizedRequest = originalRequest.newBuilder()
                    .header("Authorization", acceToken.toString())
                    .build()
                val response = chain.proceed(authorizedRequest)

                if (response.code == 401) {
                    response.close()
                    Log.e("AuthInterceptor39", "Get WAatt")
                 
                    val newAccessToken = runBlocking {
                        tokenManager.refreshToken()
                        tokenManager.getAccessToken().first()
                    }

                    Log.e("AuthInterceptor51", newAccessToken.toString())
                    val newRequest = originalRequest.newBuilder()
                        .header("Authorization", "$newAccessToken")
                        .build()
                    Log.e("AuthInterceptor55", "Get$newAccessToken")

                    return chain.proceed(newRequest)





                }



                return response

        }

    }

这是我的身份验证器代码

 class Authenticate  (private val tokenManager: TokenManager,
  ): Authenticator
 {
 override fun authenticate(route: Route?, response: Response): Request? {
    runBlocking {
         tokenManager.refreshToken()
    }
    return runBlocking {
        tokenManager.refreshToken()
        val token =  tokenManager.getAccessToken().first()
        Log.e("AUthenticate22",token.toString())
        response.request.newBuilder()
            .header("Authorization", token.toString())
            .build()
    }
}

     }
Android 改装 匕首柄 拦截 android-authenticator

评论


答: 暂无答案