В моем приложении Android, написанном на Kotlin, я использую Google Sign-In для авторизации и токены JWT для аутентификации с помощью моего внутреннего API. Срок действия моих токенов JWT и токена JWT в Google Sign-In истекает через 1 час.
Я хочу, чтобы мое приложение повторно авторизировалось с помощью Google Sign-In и повторно аутентифицировалось с моим API при запросе к моему внутреннему API завершается с ошибкой 401, поэтому я добавил аутентификатор в OkHttpClient.
Однако, когда я запускаю приведенный ниже код, задача silentSignIn навсегда блокируется и не отвечает в строке val result = Tasks.await(task)
.
Я что-то упускаю из виду? Я не могу найти причину того, почему silentSignIn () блокируется при вызове из аутентификатора.
В других местах я не использую Tasks.await(task)
, так как там я использую OnCompleteListener
для обновления Пользовательский интерфейс, обновите переменные apiToken
и googleToken
, однако в приведенном ниже коде я хотел обновить apiToken
и googleToken
, когда запрос не прошел, не требуя, чтобы другой код в моем проекте перезапустил запрос на API бэкэнда.
TLDR: я хочу вызвать GoogleSignIn.silentSignIn () в AutHenticator OkHttpClient, получить токен и немедленно повторить запрос, но мое приложение зависает на Tasks.await.
val RC_SIGN_IN = 9001
var apiToken: String? = null
var googleToken: String? = null
val client: OkHttpClient = OkHttpClient
.Builder()
.authenticator(object : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
return if (response.code == 401) {
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
val gso =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken("token_goes_here")
.build()
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
val googleSignInClient = GoogleSignIn.getClient(this@MainActivity, gso)
val task = googleSignInClient.silentSignIn().addOnCompleteListener {
val result = it.getResult(ApiException::class.java)
googleToken = result?.idToken
}.addOnFailureListener {
val signInIntent = googleSignInClient.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
if (task.isSuccessful) {
googleToken = task.result?.idToken
} else {
try {
/**** The following line is where the routine locks up: ****/
val result = Tasks.await(task)
googleToken = result?.idToken
} catch (ex: ExecutionException) {
// task failed
Log.e(TAG, "authenticate error:{ex}")
} catch (ex: InterruptedException) {
// an interrupt occurred while waiting for the task to finish
Log.e(TAG, "authenticate error:{ex}")
}
}
apiToken = getApiToken(googleToken)
response.request
.newBuilder()
.header("Authorization", "Bearer $apiToken")
.build()
} else {
null
}
}
}
)
.build()