我在Interactive Brokers有一个帐户。他们有一个不错的交易API,但是没有API可以访问他们在https://www.interactivebrokers.com/sso/Login的网站上提供的一些帐户管理功能。我查看了一下javascript,他们正在加密用户名&用javascript在浏览器中输入密码,然后通过SSL发送加密的东西。
我希望能够在c#中做到这一点。第一步(我认为)是使用HttpWebRequest或WebClient打开https://www.interactivebrokers.com/sso/Login来获取会话ID(这只是加载登录页面 - 甚至没有输入任何用户名或密码)。
代码中没有太多突破性的东西。 WebClient版本是:
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
Stream data = client.OpenRead("https://www.interactivebrokers.com/sso/Login");
HttpWebRequest版本无论如何都无法写回家:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.interactivebrokers.com/sso/Login");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
然而,在我这样做的任何一种情况下,我都会得到一个
The remote server returned an error: (400) Bad Request.
我尝试按照Why Does my HttpWebRequest Return 400 Bad request?添加用户代理:
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
和
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)";
我仍然得到(400)错误。
内部异常为null,但查看WebException的流会显示以下响应(我不知道为什么标题会显示'200 OK'):
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>200 OK</title>
</head><body>
<h1>OK</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
我查看了执行请求的Web浏览器和我的c#代码之间的数据包差异,我注意到的第一个区别是Web浏览器有更多的cypher套件,然后是我的c#代码。当服务器响应Web浏览器时,它会选择c#客户端中不可用的其中一个密码。如何将Cypher套件添加到HttpWebRequest / WebClient?我还没弄清楚这究竟是不是问题。
我错过了一些非常基本的东西吗?为什么我甚至无法使用HttpWebRequest或WebClient加载该页面?
由于
答案 0 :(得分:1)
事实证明,需要两个标头(HttpWebRequest上的属性):UserAgent&amp;接受。这是我应该发现的WireShark,但使用Fiddler使得比较标题更容易一些。因为我正在比较fiddler中的CONNECT会话而放慢速度,并且更改useragent不会影响连接头(不知道为什么,但我认为并不重要)。在CONNECT正确反映了我在HttpWebRequest上设置的属性后,下一行向下,然后我就能找出错误。
感谢Eric Law让我朝着正确的方向前进。与Cyphers无关:)