我对任何形式的帮助,可以帮助我解决这个问题,万分感谢。
从Excel VBA代码,我需要下载和解析来自HTTPS网站CSV文件https://redmine.itransition.com/ 。 我尝试使用的WinHTTP来获取文件。 不过,我不明白为什么验证不起作用。 这里是一块相关的代码:
TargetURL = "https://redmine.itransition.com/projects/pmct/time_entries.csv"
Set HTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
HTTPReq.Option(4) = 13056 ' WinHttpRequestOption_SslErrorIgnoreFlags 13056: ignore all err, 0: accept no err
HTTPReq.Open "GET", TargetURL, False
HTTPReq.SetCredentials "UN", "PW", 0
HTTPReq.send
返回以下响应(只有特定字符串是列出):
Content-Type: text/html; charset=utf-8
Status: 406
X-Runtime: 5
不过,如果我利用成功的手动认证之后火狐发送cookie“曲奇”串
HTTPReq.setRequestHeader "Cookie", SetCookieString
HTTPReq.send
我很容易得到预期的文件。 当然,我不是很满意这样的解决方案,并要执行真正的WinHTTP的验证。 不过,我不明白什么是错的还是我在我的代码错过了什么。 最有可能我不得不使用.SetClientCertificate
方法,但不清楚这个对我来说-这证书是必需的?
或者,更加一般:它WinHTTP的方法或函数应该使用调试找出哪些步骤是阻止/不正确的,让我无法正确的验证? 我待了两个星期通过MSDN和各种资源寻找,但仍然没有解决。
在此先感谢您的建议!
在登录https://redmine.itransition.com/仅仅是一个HTML形式的职位,在用户名和密码的脚本/login
。
这是不兼容SetCredentials
这是专为像基本/摘要/ NTLM基于服务器的身份验证方案。
你需要加载一个页面,没有凭据,抢什么样子的挥发性场authenticity_token
生成表单及后,随着用户名和密码/login
。
如果它是一个基于会话的系统,它将响应与Set-cookie头+数据,需要在后续请求中使用。
上述@Alex K.反应正是我一直在寻找SOOOO长! 使用Firebug和MSDN的帮助下,我完成了3个请求:
- GET请求使用正则表达式从登录页面收集authenticity_token数据
- POST请求来认证&收集从反应所需的Cookie串
- GET请求最终得到我心爱的CSV
下面的一段,其正在按预期代码:
Set RegX_AuthToken = CreateObject("VBScript.RegExp")
' Below Pattern w/o double-quotes encoded: (?:input name="authenticity_token" type="hidden" value=")(.*)(?:")
RegX_AuthToken.Pattern = "(?:input name=" & Chr(34) & "authenticity_token" & Chr(34) & " type=" & Chr(34) & "hidden" & Chr(34) & " value=" & Chr(34) & ")(.*)(?:" & Chr(34) & ")"
RegX_AuthToken.IgnoreCase = True
RegX_AuthToken.Global = True
TargetURL = "https://redmine.itransition.com/login"
Set HTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
HTTPReq.Open "GET", TargetURL, False
HTTPReq.Send
Set Token_Match = RegX_AuthToken.Execute(HTTPReq.ResponseText)
AuthToken = Token_Match.Item(0).SubMatches.Item(0)
PostData = "authenticity_token=" & AuthToken & "&back_url=https://redmine.itransition.com/" & "&username=" & UN & "&password=" & PW & "&login=Login »"
HTTPReq.Open "POST", TargetURL, False
HTTPReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
HTTPReq.Send (PostData)
SetCookieString = HTTPReq.GetResponseHeader("Set-Cookie")
TargetURL = "https://redmine.itransition.com/projects/pmct/time_entries.csv"
HTTPReq.Open "GET", TargetURL, False
HTTPReq.setRequestHeader "Cookie", SetCookieString
HTTPReq.Send
下面的网址是建筑POST请求帮助: http://tkang.blogspot.com/2010/09/sending-http-post-request-with-vba.html
你需要加载一个页面,没有凭据,抢什么样子生成表单和后挥发场authenticity_token,随着用户名和密码/登录。
亚历克斯K. - 在辉煌的建议,再次感谢! (:
还有一件事(除上述解决方案)应该意识到在使用POST请求类似于上面的代码的情况下:对于一些模糊的原因我仍然有曾经在4-5倍(甚至更多)的痛恨406从网站,这意味着在我的情况AUTH响应是不完整的 。 后一步一步的调试小时我愉快地陷入的原因:身份验证令牌值可以具有+
迹象,并从分析的几十身份验证令牌的箭头/响应代码我发现, +
含令牌完全匹配406码。
该解决方案变得很明显:安全URL编码+
ES的PostData
。 的帮助下http://www.blooberry.com/indexdot/html/topics/urlencoding.htm我终于想出了以下内容:
PostData = "authenticity_token=" & Replace(AuthToken, "+", "%2B", vbTextCompare) & _
"&back_url=https://redmine.itransition.com/projects/" & Trim(RedmineProject) & _
"/time_entries" & "&username=" & UN & "&password=" & PW & "&login=Login »"
+
ES被取代%2B
秒,这是-没有更多的406S)!
其他特殊字符不会在我的情况下无所谓,但这个教训教训。 希望这将节省几个小时的寿命了别人!