我已经设置了一个功能完善的应用程序(在VB中),允许用户访问他的Google表格。
该应用程序遵循Google的OAuth文档,在Web浏览器中显示登录对话框,获取用户的权限和访问代码,使用访问代码获取访问令牌,然后使用Google表格的查询服务获取Google表格。很简单。工作正常。
在定义了互联网代理的计算机上出现问题。在我的应用程序的其余部分和大多数Google Sheets API中,我可以定义一个手动互联网代理。GData 的 RequestFactory 允许手动配置代理服务器。唯一不支持的代码行(据我目前所知)是用于获取访问令牌的 OAuthUtil 库。它不允许定义互联网代理服务器,因此它无法解析代理环境后面的计算机上的主机。以下是我的伪代码:
Dim parameters As New OAuth2Parameters
parameters.ClientId = CLIENT_ID
parameters.ClientSecret = CLIENT_SECRET
parameters.RedirectUri = REDIRECT_URI
parameters.Scope = SCOPE
>>Show browser window and obtain access code
parameters.AccessCode = login.Token
OAuthUtil.GetAccessToken(parameters) '<< Point of failure
Dim requestFactory As GOAuth2RequestFactory = New GOAuth2RequestFactory(Nothing, My.Application.Info.ProductName, parameters)
requestFactory.Proxy = GetProxySettings() '<< my code for defining proxy
myService = New SpreadsheetsService("Application")
myService.RequestFactory = requestFactory
另一个重要的方面是我的应用程序也可以在Mac OSX上使用Wine(对于Web浏览器,我使用GeckoFX)。如果互联网代理是在环境中全局定义的,那么OAuthUtil工作正常,但这不适用于Wine。我尝试在命令行环境中或在注册表中设置互联网代理并刷新系统设置,但在 Wine 中运行的应用程序仍然不了解已定义代理。因此,必须手动定义代理。
我需要帮助来找出以下任何一种解决方案:* 一种强制/手动定义 OAuthUtil 代理以获取访问令牌的方法* 如果无法按上述方式定义代理,则任何其他获取OAuth访问令牌的方法(也许可以使用WebClient?* 在 Wine 中定义全局互联网代理的某种方法,以便像 GData API 这样的应用程序读取并理解代理设置。虽然我更喜欢在应用程序级别手动定义的代理。
伙计们有什么想法吗?
问候法
我已经想通了。事实证明,"OAuthUtil.GetAccessToken"仅使用系统定义的代理。没有办法像RequestFactory支持那样手动定义互联网代理。因此,使用WebClient有一个解决方法:
Try
'// Get access token from code
Using WC As New WebClient
' Define proxy
WC.Proxy = GetProxySettings()
' Set parameters
WC.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
' Get response
Dim postURL = "https://www.googleapis.com/oauth2/v4/token"
Dim postParams = "code=" & parameters.AccessCode &
"&client_id=" & Uri.EscapeDataString(CLIENT_ID) &
"&client_secret=" & Uri.EscapeDataString(CLIENT_SECRET) &
"&redirect_uri=" & Uri.EscapeDataString(REDIRECT_URI) &
"&grant_type=authorization_code"
Dim responsebody As String = WC.UploadString(postURL, postParams)
' Read response
Dim jObj As JObject = JsonConvert.DeserializeObject(responsebody)
' Store token
parameters.AccessToken = jObj("access_token").ToString
parameters.RefreshToken = jObj("refresh_token").ToString
parameters.TokenType = jObj("token_type").ToString
parameters.TokenExpiry = Now().AddSeconds(CDbl(jObj("expires_in").ToString))
End Using
Catch ex As Exception
MsgBox("Error obtaining access token: " & ex.Message, MsgBoxStyle.Critical)
Return Nothing
End Try