用程序登录Aps.Net页面
2024-07-10 13:12:09
供稿:网友
在写internet应用程序的时候,常常需要处理用户登录的情况。一般来说,对于这种情况,我们是使用程序来模拟用户在web页面上填写用户名、密码并提交的过程。当用户在web页面上输入了用户名、密码并提交之后,实际上是触发了一个post请求,在这个请求中包含有用户名、密码等信息。因此,我们只要在程序中将相关信息封装成一条post请求,并将它发送给web server,基本上就能实现登录了。以mfc为例,下面的这段代码模拟了一个登录过程:
cstring strheaders = _t("content-type: application/x-www-form-urlencoded");
// name = "sam", password = "123", action = "submit"
cstring strformdata = _t("name=sam&password=123&action=submit");
cinternetsession session;
chttpconnection* pconnection =
session.gethttpconnection(_t("servernamehere"));
chttpfile* pfile =
pconnection->openrequest(chttpconnection::http_verb_post,
_t("formactionhere"));
bool result = pfile->sendrequest(strheaders,
(lpvoid)(lpctstr)strformdata, strformdata.getlength());
这个方法对于asp页面很有效,但对于asp.net页面,有时却不起作用,这是为什么呢?
为了搞清出asp.net页面在处理登录时与asp页面有何区别,我们需要使用sniffer工具来跟踪web服务器与浏览器之间的通讯。经过跟踪会发现,asp.net页面在用户提交登录信息之后,仍然是使用post请求将相关信息发送给服务器。所不同的是,处理用户名、密码等信息之外还多了一个__viewstate。如果在上面代码中的strformdata中加上一个通过sniffer得到的__viewstate的话,就能够成功模拟出整个登录过程了。接下来的问题就是,我们应该如何获得这个__viewstate呢?
我们知道,asp.net页面有一个viewstate属性,asp.net用它来保存页面的状态信息,以便在页面提交失败时,能够恢复页面的状态。它是通过页面中的一个隐藏的域来定义的,如果通过浏览器来view source的话,可以看到它是如下的一行代码
它的value值正是我们所需要的,我们只要从登录页面中解析出这个__viewstate的value,我们的问题就能够得到解决了。
仔细看一下,viewstate的值是经过编码的,先不管它,直接将它从页面中取出,和登录信息一起组成post请求,发送给server,结果如何呢?失败了l。对比一下sniffer的结果和页面中viewstate的value,我们会发现,它们之间还是有些许不同的。原来,页面源码中的viewstate值是经过base64编码的,而当它被发送给web server时,为了保证传输的正确,浏览器会将它转换成url编码,当web server接收到viewstate之后,当然会先将它从url编码解码为base64编码再交给asp.net处理。看来我们需要将viewstate的值在进行一边url编码处理,这样就能够成功模拟整个登录过程了j。
参考
1. howto: simulate a form post request using wininet,微软的kb文章,描述了模拟post请求的实现。
2. asp .net maintaining the viewstate,viewstate的入门知识。
3. viewstate: all you wanted to know,关于viewstate的深入讨论。
4. viewstate parser,想看看解码后的viewstate是什么样子吗?试试这个parser。
5. 博客堂中的相关讨论,这是我在解决这个问题的过程中,在博客堂写的blog。