Нормальные токены

This commit is contained in:
Халимов Рустам
2026-04-19 22:55:38 +03:00
parent f6400ce3ac
commit 945134f029
15 changed files with 116 additions and 14 deletions
+49 -8
View File
@@ -5,9 +5,7 @@ import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.launch
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.runBlocking
@Singleton
class AuthInterceptor @Inject constructor(
@@ -15,6 +13,10 @@ class AuthInterceptor @Inject constructor(
private val navigationManager: core.utils.NavigationManager,
private val authRepositoryProvider: javax.inject.Provider<auth.domain.repository.AuthRepository>
) : Interceptor {
@Volatile
private var isRefreshing = false
override fun intercept(chain: Interceptor.Chain): Response {
val token = tokenManager.getToken()
val request = chain.request().newBuilder().apply {
@@ -23,16 +25,55 @@ class AuthInterceptor @Inject constructor(
}
}.build()
val response = chain.proceed(request)
var response = chain.proceed(request)
if (response.code == 401) {
// Global logout
kotlinx.coroutines.GlobalScope.launch(kotlinx.coroutines.Dispatchers.Main) {
authRepositoryProvider.get().logout()
navigationManager.logout()
// Attempt to refresh token synchronously
val refreshedToken = refreshAuthToken()
if (refreshedToken != null) {
// Close the old response before retrying
response.close()
// Retry the original request with the new token
val retryRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $refreshedToken")
.build()
response = chain.proceed(retryRequest)
} else {
// Refresh failed, logout
logoutUser()
}
}
return response
}
private fun refreshAuthToken(): String? {
if (isRefreshing) {
// Already refreshing, wait and return current token
return tokenManager.getToken()
}
return runBlocking {
isRefreshing = true
try {
val result = authRepositoryProvider.get().refreshToken()
if (result.isSuccess) {
result.getOrNull()?.token
} else {
null
}
} finally {
isRefreshing = false
}
}
}
private fun logoutUser() {
runBlocking {
authRepositoryProvider.get().logout()
}
navigationManager.logout()
}
}
+9 -2
View File
@@ -20,11 +20,14 @@ class TokenManager @Inject constructor(context: Context) {
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
fun saveToken(token: String, userId: String? = null) {
fun saveToken(token: String, userId: String? = null, refreshToken: String? = null) {
val editor = prefs.edit().putString("jwt_token", token)
if (userId != null) {
editor.putString("user_id", userId)
}
if (refreshToken != null) {
editor.putString("refresh_token", refreshToken)
}
editor.apply()
}
@@ -32,11 +35,15 @@ class TokenManager @Inject constructor(context: Context) {
return prefs.getString("jwt_token", null)
}
fun getRefreshToken(): String? {
return prefs.getString("refresh_token", null)
}
fun getUserId(): String? {
return prefs.getString("user_id", null)
}
fun deleteToken() {
prefs.edit().remove("jwt_token").remove("user_id").apply()
prefs.edit().remove("jwt_token").remove("user_id").remove("refresh_token").apply()
}
}