我不知道你是否可以帮助我理解这个问题的正确方法。我需要先提供一点背景知识。
我有一个使用 Google V3 Calendar API 的VB.Net控制台实用程序。此实用程序具有身份验证:
的以下过程Private Function DoAuthentication(ByRef rStrToken As String, ByRef rParameters As OAuth2Parameters) As Boolean
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
'm_Scopes.Add(CalendarService.Scope.Calendar)
m_Scopes.Add("https://www.googleapis.com/auth/calendar https://www.google.com/m8/feeds/ https://mail.google.com/")
Try
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("PublicTalkSoftware.Calendar.Application")).Result()
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "~~~~~~~~~~"
}
m_Service = New CalendarService(initializer)
rStrToken = credential.Token.AccessToken.ToString()
rParameters.AccessToken = credential.Token.AccessToken
rParameters.RefreshToken = credential.Token.RefreshToken
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
Return False
End Try
Return True
End Function
这部分申请流程运作正常。数据存储文件被创建,一旦用户验证了它,所有似乎只是从那里工作找到。用户将能够更新日历而无需进一步验证部分。
现在,我还有一个MFC(主应用程序)项目的一部分,它为用户发送电子邮件。这使用以下CkMainManW库。
在大多数情况下也有效。如果用户已正确设置其凭据,则可以。但是,如果他们使用 GMail ,那么我的处理方式略有不同。这是为了避免需要允许第三方应用程序"选项可在Google帐户中打勾。
因此,对于GMail用户,我们会发送以下电子邮件:
mailman.put_SmtpUsername(strUsername);
mailman.put_OAuth2AccessToken(strGoogleToken);
如您所见,我使用 OAuth2AccessToken 。传递的实际值是用户进行身份验证时存储的credential.Token.AccessToken.ToString()
值。现在,我已经明白这个实际令牌只能持续一小时。这可以解释为什么有些用户必须再次重复运行我的日历身份验证才能获得新的访问令牌。
显然,当我执行使用数据存储文件的日历身份验证时,它会做一些事情,避免用户被问到所有时间进行身份验证。
现在,我已阅读此tutorial关于使用 Chilkat库的信息。我现在注意到它在示例代码中有一个注释:
// Now that we have the access token, it may be used to send as many emails as desired
// while it remains valid. Once the access token expires, a new access token should be
// retrieved and used.
那么,在所有背景下,如何解决我的问题?所以我有一个数据存储文件,其中包含授权时的原始访问令牌和刷新令牌。该文件由VB.Net命令行模块创建。
听起来,Chilkat例程需要一个有效的访问令牌。那么,从刷新令牌获取更新的访问令牌的正确方法是什么,这样当我发送电子邮件时,它会在一小时后失败?
我让自己感到困惑。我更改了我的代码,以便调用上面的DoAuthentification
调用来获取刷新令牌和访问令牌。但我发现实际的数据存储文件没有得到修改。文本文件未被修改。
我必须撤销访问权限,然后进行身份验证以修改数据存储文件。只有在修改后,访问令牌才能用于发送电子邮件。
答案 0 :(得分:1)
我想我找到了解决方案。我看到了这个答案:
https://stackoverflow.com/a/33813994/2287576
根据答案我添加了这个方法:
Private Function RefreshAuthentication(ByRef rStrAccessToken As String, ByRef rStrRefreshToken As String) As Boolean
Dim parameters As New OAuth2Parameters
With parameters
.ClientId = m_strClientID
.ClientSecret = m_strClientSecret
.AccessToken = rStrAccessToken ' Needed?
.RefreshToken = rStrRefreshToken
.AccessType = "offline"
.TokenType = "refresh"
.Scope = "https://www.googleapis.com/auth/calendar https://www.google.com/m8/feeds/ https://mail.google.com/"
End With
Try
Google.GData.Client.OAuthUtil.RefreshAccessToken(parameters)
rStrAccessToken = parameters.AccessToken
rStrRefreshToken = parameters.RefreshToken
RefreshAuthentication = True
Catch ex As Exception
RefreshAuthentication = False
End Try
End Function
我不确定在刷新之前是否需要传入现有的访问令牌。但不管怎样,令牌都会更新,我可以继续发送电子邮件。
答案 1 :(得分:0)
仅供参考,最后很明显我根本不需要任何定制的刷新,因为系统会在幕后为您管理它。
Private Async Function DoAuthenticationAsync() As Task(Of Boolean)
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
Try
credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("xxx.Calendar.Application"))
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "yy"
}
m_Service = New CalendarService(initializer)
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
' Can we isolate that as the exception?
m_logger.Error(ex, "DoAuthenticationAsync")
Return False
End Try
Return True
End Function
我已经很长时间不需要任何定制的令牌刷新了。