[英]how to refresh Bearer Token using retrofit android Kotlin
雖然登錄應用程序我可以獲得令牌,刷新令牌並保存它但我不知道 session 何時結束令牌如何更新。 如何在其中添加攔截器以更新令牌或可以使用其他一些方法? 這是我的代碼
1- Api 端點
@POST("identity/Identity/GetRefreshToken")
suspend fun refreshToken(): AuthTokenEntityDT0
2- AuthTokenEntityDT0 響應
data class AuthTokenEntityDT0(
@SerializedName("accessToken") val accessToken: String,
@SerializedName("refreshToken") val refreshToken: String,
@SerializedName("statusCode") val statusCode: Int,
@SerializedName("statusMessage") val statusMessage: String,
)
3 - 在這里提出請求
@Provides
@Singleton
fun provideAPIService(): ApiService {
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.addHeader("Content-Type", "application/json; charset=UTF-8")
.addHeader("user-agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
.addHeader("Authorization", "Bearer $access_token")
val request = requestBuilder.build()
chain.proceed(request)
}
.build()
val retrofit = Retrofit.Builder()
.baseUrl(NativeBaseUrl.getBaseUrl())
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
return retrofit.create(ApiService::
class.java)
}
@Provides
fun provideApiRepository(apiService: ApiService): ApiRepository {
return ApiRepositoryImpl(apiService)
}
4 -
問題:refreshToken Api 反復調用我如何停止它並繼續前進,盡管我已將 Dispatcher 用於一個請求以像這樣前進
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
val dispatcher = Dispatcher()
dispatcher.maxRequests = 1
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(ForbiddenInterceptor(this))
.dispatcher(dispatcher)
.addInterceptor(interceptor)
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.addHeader("Content-Type", "application/json;
charset=UTF-8")
.addHeader("user-agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X
10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
.addHeader("Authorization", "Bearer $access_token")
val request = requestBuilder.build()
chain.proceed(request)
}
.build()
5- 這是我的攔截器
class ForbiddenInterceptor(var hIltModules: HIltModules) :
Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val original = chain.request()
val response = chain.proceed(original)
if (response.code == 401) {
val responseRefreshTokens= runBlocking {
val originalRequests = chain.request()
val authenticationRequest = originalRequests.newBuilder()
.addHeader("refreshtoken", "${Constants.refreshToken}").build()
chain.proceed(authenticationRequest)
hIltModules.provideAPIService().refreshToken()
}
if (responseRefreshTokens.statusCode == 200) {
val originalRequests = chain.request()
val newAuthenticationRequest = originalRequests.newBuilder()
.removeHeader("refreshtoken")
.build()
access_token = responseRefreshTokens.accessToken
refreshToken = responseRefreshTokens.refreshToken
return chain.proceed(newAuthenticationRequest)
}
}
return chain.proceed(original)
}
}
我建議你把你的自定義攔截器放在它自己的 class 中,像這樣:
class ForbiddenInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request = chain.request()
val response: Response = chain.proceed(request)
if (response.code == 401) {
// this code section will run for every HTTP 401 response
}
return response
}
}
然后使用這個攔截器:
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(ForbiddenInterceptor())
.build()
將攔截器添加到 OkHttpClient 確保您將攔截調用並且您可以運行自定義代碼,檢查它是否已被服務器拒絕。
至於更新你的令牌。 您可能需要實現后端的另一項服務。 我只能假設,但你必須使用你的accesToken
將它提供給端點,服務器將返回一個新的refreshToken
。
這是我為刷新令牌所做的完整代碼,它可能對某些人有幫助
class AuthenticationInterceptorRefreshToken @Inject constructor(
var hIltModules: HIltModules,
) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val response = chain.proceed(originalRequest)
if (response.code == 401) {
synchronized(this) {
val originalRequest = chain.request()
val authenticationRequest = originalRequest.newBuilder()
.addHeader("refreshtoken", " $refreshToken")
.build()
val initialResponse = chain.proceed(authenticationRequest)
when (initialResponse.code) {
401 -> {
val responseNewTokenLoginModel = runBlocking {
hIltModules.provideAPIService().refreshToken()
}
when (responseNewTokenLoginModel.statusCode) {
200 -> {
refreshToken = responseNewTokenLoginModel.refreshToken
access_token = responseNewTokenLoginModel.accessToken
val newAuthenticationRequest = originalRequest.newBuilder()
.header("refreshtoken",
" $refreshToken")
.build()
return chain.proceed(newAuthenticationRequest)
}
else -> {
return null!!
}
}
}
else -> return initialResponse
}
}
}; return response
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.