我的问题:如何请求 OAuth2 凭证对象来访问 Google Drive API,即 accessToken 过期后自动刷新?
我做了什么: 我遵循了 Google 的最新建议,如何通过首先通过 Credential Manager 进行身份验证,然后通过 Google Indentiy 进行授权来访问 Android 上的 Google Drive API:
https://developers.google.com/identity/android-credential-manager https://developers.google.com/identity/authorization/android
我也在这里找到了帮助:
如何使用 CredentialManager 验证 Google Sign In 并授权 Android 中的 Google Drive API?
我当前的身份验证代码如下(对于使用凭据管理器,Google 很容易找到许多好的代码示例):
private fun authorizeGoogleDrive() {
val requestedScopes = listOf(Scope(DriveScopes.DRIVE_READONLY))
val authorizationRequest = AuthorizationRequest.Builder()
.setRequestedScopes(requestedScopes)
.build()
Identity.getAuthorizationClient(this)
.authorize(authorizationRequest)
.addOnSuccessListener { authorizationResult ->
if (authorizationResult.hasResolution()) {
val pendingIntent = authorizationResult.pendingIntent
try {
val intentSenderRequest = pendingIntent?.let { IntentSenderRequest.Builder(it.intentSender).build() }
intentSenderRequest?.let { authorizeGoogleDriveResultReceiver.launch(intentSenderRequest) }
} catch (e: IntentSender.SendIntentException) {
Log.e(LOG, "SignInActivity/authorizeGoogleDrive Couldn't start Authorization UI: " + e.localizedMessage)
}
} else {
buildDriveService(authorizationResult)
}
}
}
private val authorizeGoogleDriveResultReceiver = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val authorizationResult: AuthorizationResult = Identity.getAuthorizationClient(
this
).getAuthorizationResultFromIntent(result.data)
buildDriveService(authorizationResult)
} else {
Log.e(LOG, "SignInActivity/authorizeGoogleDriveResultReceiver result.resultCode != Activity.RESULT_OK")
}
}
fun buildDriveService(authorizationResult: AuthorizationResult) {
val accessToken = AccessToken(authorizationResult.accessToken, Date(System.currentTimeMillis() + 3600 * 1000))
val credential = GoogleCredentials.create(accessToken)
driveService = Drive.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
GsonFactory.getDefaultInstance(),
HttpCredentialsAdapter(credential)
)
.setApplicationName(app_name)
.build()
}
访问运行良好一段时间(60 分钟),但随后我使用我的driveService 对象遇到以下异常:
OAuth2Credentials实例不支持刷新访问 令牌。应使用具有新访问令牌的实例,或者 支持刷新的派生类型。
真正奇怪的是:当我重新启动应用程序时,我总是获得相同的访问令牌,无论我再次调用 Identity.getAuthorizationClient(this).authorize(authorizationRequest) 。
根据 com.google.auth.oauth2.GoogleCredentials with extends OAuth2Credentials 的文档,不支持刷新访问令牌。
我尝试从GoogleCredentials切换到com.google.auth.oauth2.UserCredentials,希望这个类支持自动令牌刷新。 但我还无法成功使用它的Builder,总是出现空指针异常。我还需要一个调用此生成器的刷新令牌:
val userCredentials = UserCredentials.newBuilder()
.setClientId(app_name)
.setAccessToken(accessToken)
.setRefreshToken(refreshToken)
.build()
但是我没有refreshToken。在我通过Identity.getAuthorizationClient(this).authorize(authorizationRequest)获得的authorizationResult对象中,只有一个归档的accessToken,但没有refreshToken。
我能做什么?
我在推送通知的 firebase OAuth 令牌方面遇到了同样的问题。我做的解决方案如下:
1。在Java中,我将令牌生成时间存储在代码中,每次检查令牌生成时间是否低于55分钟,然后我给旧令牌,其他我将生成新令牌,替换为旧令牌,然后我向firebase请求推送通知
这对我来说是 Java 的工作
希望这对您也有帮助。