OAuth2 google Drive AccesToken 使用 Google Credential Manager + AuthorizationClient 刷新

问题描述 投票:0回答:1

我的问题:如何请求 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 的文档,不支持刷新访问令牌。

https://cloud.google.com/java/docs/reference/google-auth-library/latest/com.google.auth.oauth2.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。

我能做什么?

google-drive-api google-oauth google-identity android-credential-manager
1个回答
0
投票

我在推送通知的 firebase OAuth 令牌方面遇到了同样的问题。我做的解决方案如下:

1。在Java中,我将令牌生成时间存储在代码中,每次检查令牌生成时间是否低于55分钟,然后我给旧令牌,其他我将生成新令牌,替换为旧令牌,然后我向firebase请求推送通知

这对我来说是 Java 的工作

希望这对您也有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.