You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Microsoft Access VBA中调用Dropbox /oauth2/token接口失败求助

问题描述

我无法在Microsoft Access VBA中调用Dropbox的/oauth2/token接口获取有效令牌。

之前我用手动生成的临时access token,能通过以下VBA代码成功下载Dropbox文件:

Dim xmlhttp As Object
Dim myurl As String

Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
myurl = "https://content.dropboxapi.com/2/files/download"

Dim argumentString As String
argumentString = "{" & Chr(34) & "path" & Chr(34) & ":" & Chr(34) & "/testfile.txt" & Chr(34) & "}"

'argumentString 最终格式为 {"path":"/testfile.txt"}

xmlhttp.Open "POST", myurl, False
xmlhttp.SetRequestHeader "Authorization", "Bearer TemporaryGeneratedAccessToken"
xmlhttp.SetRequestHeader "Dropbox-API-Arg", argumentString
xmlhttp.send
    
MsgBox (xmlhttp.ResponseText)

If xmlhttp.Status = 200 Then
    Set oStream = CreateObject("ADODB.Stream")
    oStream.Open
    oStream.Type = 1
    oStream.Write xmlhttp.responseBody
    oStream.SaveToFile MyPCPathToWriteTo, 2
    oStream.Close
End If

但临时token有效期太短,没法用于正式场景,所以我想实现Dropbox的OAuth 2.0离线访问流程,已经完成两步:

  • 创建了权限足够的Dropbox应用
  • 通过授权链接拿到了authorization code

现在卡在用authorization code换access token和refresh token的步骤,试了两段代码都失败,返回错误:Invalid_request. The Request parameters do not match any of the supported authorization flows. Please refer to the API documentation for the correct parameters.

尝试过的代码1:

Dim xmlhttp As Object
Dim myurl As String

Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")

myurl = "https://api.dropboxapi.com/oauth2/token"
'myurl = "https://api.dropbox.com/oauth2/token"

xmlhttp.Open "POST", myurl, False

xmlhttp.SetRequestHeader "code", "MY AUTHORIZATION CODE"
xmlhttp.SetRequestHeader "grant_type", "authorization_code"

xmlhttp.SetRequestHeader "client_id", "MyAppKey"
xmlhttp.SetRequestHeader "client_secret", "MySECRETAppKey"

xmlhttp.send argumentString

MsgBox (xmlhttp.ResponseText)

尝试过的代码2(对Client ID和Secret做Base64编码):

Dim xmlhttp As Object
Dim myurl As String
Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
myurl = "https://api.dropboxapi.com/oauth2/token"
Dim argumentString As String

xmlhttp.Open "POST", myurl, False

xmlhttp.SetRequestHeader "code", "MyAuthorizationCode"
xmlhttp.SetRequestHeader "grant_type", "authorization_code"

Dim ClientID As String
Dim ClientSec As String

ClientID = EncodeBase64(StrConv("AppID", vbFromUnicode))
ClientSec = EncodeBase64(StrConv("AppSecretID", vbFromUnicode))

xmlhttp.SetRequestHeader "client_id", ClientID
xmlhttp.SetRequestHeader "client_secret", ClientSec

xmlhttp.send argumentString
MsgBox (xmlhttp.ResponseText)

我也试过把参数放到argumentString里传递,但还是同样的错误,请问哪里错了?

问题背景

我正在开发一款Access应用,需要自动更新多台PC上的前端程序。之前用OneDrive上传新版本并生成直链实现,但OneDrive API变更后这个方法失效了,所以转用Dropbox API,现在卡在OAuth授权这一步。


解决方案

你的核心错误是没有遵循Dropbox OAuth2令牌接口的参数传递规则:

  1. 参数不能放在Request Header里,必须以application/x-www-form-urlencoded格式放在请求体中
  2. 客户端身份验证有两种合规方式:要么把client_id和client_secret作为表单参数传递,要么把client_id:client_secret做Base64编码后放在Authorization Header里(格式为Basic 编码串)

下面是修正后的VBA代码(两种验证方式二选一即可):

方式一:表单参数传递客户端信息

Dim xmlhttp As Object
Dim myurl As String
Dim postData As String

Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
myurl = "https://api.dropboxapi.com/oauth2/token"

' 构造表单格式的请求体
postData = "grant_type=authorization_code" & _
           "&code=你的授权CODE" & _
           "&client_id=你的AppKey" & _
           "&client_secret=你的AppSecret"

xmlhttp.Open "POST", myurl, False
' 设置正确的Content-Type
xmlhttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.Send postData

' 查看响应结果
MsgBox xmlhttp.ResponseText

' 解析响应(如果需要)
' 成功响应会包含access_token、refresh_token、expires_in等字段
If xmlhttp.Status = 200 Then
    ' 这里可以把refresh_token保存到本地,后续用来刷新access token
End If

方式二:Basic Auth头传递客户端信息

Dim xmlhttp As Object
Dim myurl As String
Dim postData As String
Dim authString As String

Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
myurl = "https://api.dropboxapi.com/oauth2/token"

' 构造表单请求体
postData = "grant_type=authorization_code" & _
           "&code=你的授权CODE"

' 构造Basic Auth字符串:client_id:client_secret 做Base64编码
authString = "Basic " & EncodeBase64(StrConv("你的AppKey:你的AppSecret", vbFromUnicode))

xmlhttp.Open "POST", myurl, False
xmlhttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.SetRequestHeader "Authorization", authString
xmlhttp.Send postData

MsgBox xmlhttp.ResponseText

If xmlhttp.Status = 200 Then
    ' 保存refresh_token
End If

注意事项

  • 授权code只能使用一次,用过就失效,需要重新获取
  • 拿到refresh_token后,后续可以用它调用同一个接口(grant_type改为refresh_token)刷新access token,不用再走授权流程
  • 确保你的EncodeBase64函数能正确处理字符串编码,避免乱码导致验证失败

内容的提问来源于stack exchange,提问作者Mawimu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 03:45:00