2013-04-09 75 views
2

我遇到了使用请求库为登录功能编写验收测试的问题。登录是使用post方法实现的,我无法直接更改查询字符串并操作url。我想要做的是手动提交发布数据,并将页面重定向到它将经常访问的页面,如果用户成功登录。我想检索该页面的html并检查登录成功,我会这样做吗?使用请求库进行验收测试(python)

此方法将失败:

data={'email': '[email protected]', 'password': 'example'} 

login_url="examplepage.com/signin" 

request_data = requests.post(login_url, data, allow_redirects=True) 

print request_data.content 

这是resp.headers回报:

{'content-length': '1124', 'date': 'Sun, 14 Apr 2013 16:12:51 GMT', 'set-cookie': 'session="+udnwfCkuAuFGp9QKOiU1YS2X1s=?_fresh=STAwCi4=&_id=Uyc3XHhkZVx4Y2J3T1x4YjBceDkxeFx4MWNceGFhXHhkNFx4OTMhKVx4MGJyJwpwMQou&csrf=Uyc2Mzk0YjVjZjMzMGZkMTNkY2NiM2EzZTZkYzgyMjhkY2IwOWQ2NmM3JwpwMQou"; Path=/; HttpOnly', 'content-type': 'text/html; charset=utf-8', 'connection': 'keep-alive', 'server': 'Werkzeug/0.8.3 Python/2.7.3'}

resp.content刚刚返回符号的HTML页面:

<title>Web App</title> 

    </head> 
    <body> 
    <div>Web App: <a href="/home">Home</a> 

      | <a href="/signin">Login</a> 
      | <a href="/register">Register</a> 

    </div> 
    <hr> 




<h1>Sign in</h1> 


<form action="" method=post name="signin"> 
    <div style="display:none;"><input id="csrf_token" name="csrf_token" type="hidden" value="20130414164251##fd7e82d47974518d098b41cecf2a4452f890317f"></div> 
    <dl> 

    <dt><label for="email">Email Address</label> 
    <dd><input id="email" name="email" type="text" value="[email protected]"> 

    </dd> 


    <dt><label for="password">Password</label> 
    <dd><input id="password" name="password" type="password" value=""> 

    </dd> 

    </dl> 
    <p><input type="submit" value="Sign in"> 
</form> 

<a href="/login"> Click here to sign in using your Google, Yahoo, AOL, Flickr, or another OpenID account. </a> 


    </body> 
</html> 
+0

它是如何,它失败了呢?什么从打印命令回来? – bbayles 2013-04-10 03:17:22

+0

这不是重定向,它只会返回页面html中的符号。 – Mike 2013-04-10 14:56:09

回答

2

如果你想登录到一个页面,我会建议创建会话,尽管st独立请求。如果您正确发送数据您应该检索一些会话cookie。我会检查它是否已经登录。当脚本登录并获取cookie时,它还应该检索包含目标页面的位置标题。尝试这样的:

import requests 
data={'email': '[email protected]', 'password': 'example'} 
login_url="examplepage.com/signin" 
s = requests.session() 
resp = s.post(login_url,data) 
#now s.cookies should contain session cookie if properly logged in 
target = s.get(resp.headers['Location']) 

但我认为这个问题可能是关于会议。

+0

我做了一些更多的研究,显然禁用CSRF并不是最聪明的想法。你能给我更多关于你建议的方法的细节吗?我试过你的代码,但我得到这个:'requests.exceptions.MissingSchema:无效的网址u'None':没有提供模式' – Mike 2013-04-14 00:41:25

+0

看起来响应不包含位置标题。这意味着您的响应标头的状态码不是301,即http重定向。你能否显示你的response.headers和response.content? – 2013-04-14 15:26:11

+0

我已将它添加到上面。 – Mike 2013-04-14 16:19:19

0

我的解决办法是从在我的应用程序的config.py文件改变CSRF_ENABLED变量。上面的代码实际上一旦我改变了这个设置。顺便说一句,我正在Heroku上主持。

+0

阅读CSRF,不建议这样做。 – Mike 2013-04-14 13:03:36

0

我这样做:

if auth == True: 
     # fetch the login page in order to get the csrf token 
     cookieHandler = urllib2.HTTPCookieProcessor() 
     opener = urllib2.build_opener(urllib2.HTTPSHandler(), cookieHandler) 
     urllib2.install_opener(opener) 

     login_url = URL 
     login_page = opener.open(login_url) 

     # attempt to get the csrf token from the cookie jar 
     csrf_cookie = None 
     for cookie in cookieHandler.cookiejar: 
      if cookie.name == 'csrftoken': 
       csrf_cookie = cookie 
       break 
     if not cookie: 
      raise IOError("No csrf cookie found") 

     # login using the usr, pwd, and csrf token 
     login_data = urllib.urlencode(dict(
      username = username, password = password, 
      csrfmiddlewaretoken = csrf_cookie.value)) 

     req = urllib2.Request(login_url, login_data) 
     resp = urllib2.urlopen(req) 
     contents = resp.read() 

    target_download = target_url 
    status_code = urllib2.urlopen(target_download).getcode() 
    our_document = urllib2.urlopen(target_download).read() 
    return status_code, our_document