【发布时间】:2021-08-03 16:42:52
【问题描述】:
我正在为我的 Google Oauth 设置使用已安装的应用程序客户端 ID。使用 GoogleWebAuthorizationBroker.AuthorizeAsync 成功进行用户身份验证后,我收到了来自 Google 的访问令牌,并且能够按预期使用 Google API。大约 1 小时后,如果我需要访问 Google API,我正在使用 [credential.RefreshTokenAsync] 函数来刷新访问令牌。即使使用刷新令牌,我也能够按预期访问 Google API。
但在随机情况下,我在刷新令牌时收到以下异常。我可以确认客户端 ID 没有问题,因为我的客户端 ID 是从永久文本文件中读取的。
更新:添加代码和更多细节。
由于 Google API 对我的应用场景的限制,我将应用设计如下:
- 用户将从 Windows 窗体应用程序设置他们的 Google 帐户。 (“首次验证码”我在下面提到)
- 我将使用在第 1 步中从 Google 收到的令牌响应,在另一个应用程序中使用相同的客户端 ID/秘密(我在下面提到的“问题场景”代码)。因此,Google API 将查看令牌响应是否已经可用,如果可用,则不会显示身份验证页面并检查令牌是否已过期。如果过期,我将使用 RefreshTokenAsync 刷新令牌。
代码:
//First time authentication
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId,
ClientSecret,
},
scopes,
GoogleAuthUser,
CancellationToken.None, new FileDataStore(filepath, true)).Result;
var oauthSerivce = new Google.Apis.Oauth2.v2.Oauth2Service(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Appname",
});
//Issue scenario:
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId,
ClientSecret,
},
Scopes,
"user",
CancellationToken.None,
new FileDataStore(filepath, true)).Result;
if (credential.Token.IsExpired(credential.Flow.Clock))
{
if (credential.RefreshTokenAsync(CancellationToken.None).Result)
{
}
else
{
}
}
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
异常详情:
(Inner Exception #0) Google.Apis.Auth.OAuth2.Responses.TokenResponseException: Error:"invalid_request", Description:"Could not determine client ID from request.", Uri:""
at Google.Apis.Auth.OAuth2.Responses.TokenResponse.<FromHttpResponseAsync>d__36.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Requests.TokenRequestExtenstions.<ExecuteAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<FetchTokenAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<FetchTokenAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<RefreshTokenAsync>d__31.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.UserCredential.<RefreshTokenAsync>d__22.MoveNext()<---
【问题讨论】:
-
也许第 4 项:blog.timekit.io/…
-
为什么不让客户端库为您刷新它,这就是它的设计目的。请编辑您的问题并包含minimal reproducible example。在我看来,要么您的客户端 ID 不正确,要么您尝试使用使用不同客户端 ID 创建的刷新令牌。
-
@jdweng 没有错误消息,它实际上表示刷新令牌已过期。
-
@DaImTo 如果客户端 ID 或刷新令牌错误,则应该始终出现该问题。正如我之前提到的,问题在测试期间随机发生。另外,我在问题中添加了更多细节。请看一下。
标签: c# oauth-2.0 google-oauth google-api-dotnet-client