我在 Access 2007 VBA 中使用 WinHTTP 来获取一些需要 cookie 登录凭据帐户的项目列表。
首先我通过https://www.example.com/login.php登录有了这个:
Dim strCookie As String, strResponse As String, _
strUrl As String
'
Dim xobj As Object
'
Set xobj = New WinHttp.WinHttpRequest
'
strUrl = "https://www.example.com/login.php"
xobj.Open "POST", strUrl, False
xobj.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
xobj.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xobj.Send "username=johndoe2&password=mypassword"
'
strCookie = xobj.GetResponseHeader("Set-Cookie")
strResponse = xobj.ResponseText
strResponse 的内容表示我的登录正常,因为此字符串中欢迎 johndoe2。 strCookie保存了登录成功后HTTP服务器返回的Set-Cookie。
接下来我需要获得一个只有登录用户才能访问的 secret 页面:https://www.example.com/secret-contents.php .我这样做,使用之前的 Set-Cookie header strCookie,重新发送到服务器:
'
' now try to get confidential contents:
'
strUrl = "https://www.example.com/secret-contents.php"
xobj.Open "GET", strUrl, False
xobj.SetRequestHeader "Cookie", strCookie
xobj.Send
'
strCookie = xobj.GetResponseHeader("Set-Cookie")
strResponse = xobj.ResponseText
不幸的是,它失败了,因为新的 strResponse 表明获取的内容不是必需的内容,而是登录页面。而且 strCookie 也发生了变化。
这已经过测试并没有产生任何效果,因为它仅适用于Windows/OS 链接的身份验证,例如著名的基本、NTLM、摘要和Kerberos 身份验证,不适用于基于cookie 的身份验证:
xobj.SetCredentials "johndoe2", "mypassword", 0
除了 Set-Cookie 之外,还需要将什么作为 header 发送到远程服务器,以便使用先前认证的凭据?
服务器使用typo3 CMS框架。
最佳答案
这半天终于想通了如何使用之前的登录凭证进行后续的请求,感谢Alex K.的帮助, fiddler2打开了进入 HTTP header 世界的大门。我想分享今天对我有用的东西。
该工作包括 2 个步骤,通过 URL1 登录,然后获取所需凭据的 HTML 内容 URL2。
1。通过 URL1 登录,与问题中保持相同:
Dim strCookie As String, strResponse As String, _
strUrl As String
'
Dim xobj As Object
'
Set xobj = New WinHttp.WinHttpRequest
'
strUrl = "https://www.example.com/login.php"
xobj.Open "POST", strUrl, False
xobj.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
xobj.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xobj.Send "username=johndoe2&password=mypassword"
'
strCookie = xobj.GetResponseHeader("Set-Cookie")
strResponse = xobj.ResponseText
2。获取用户名/密码保护的URL2的内容:
'
' now try to get confidential contents:
'
strUrl = "https://www.example.com/secret-contents.php"
xobj.Open "GET", strUrl, False
'
' these 2 instructions are determining:
'
xobj.SetRequestHeader "Connection", "keep-alive"
xobj.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
'
xobj.SetRequestHeader "Cookie", strCookie
xobj.Send
'
strCookie = xobj.GetResponseHeader("Set-Cookie")
strResponse = xobj.ResponseText
注意到在第二步中使用了两个额外的 header 发送到 HTTP 服务器:
“连接”、“保持事件”
“User-Agent”,“我假装的导航器 blabla...”
没有它们,URL2 将无法成功获取,相反,一个配置良好的网站会将您重定向到 URL1 以再次进行身份验证。
简而言之, session 必须有一个keep-alive连接才能重新使用获得的登录凭证。
这对 http 和 https 协议(protocol)没有影响。
HTML 登录输入字段名称取决于目标站点,此处为用户名 和密码。 本网站的设计者可能会使用用户、通过等词语; 登录用户, 登录密码; ...您可以通过查看登录表单的源代码轻松解决这个问题。
关于vba - WinHTTP VBA 后续请求不能使用之前的登录凭据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19294956/