Pylons应用中的授权单元测试失败;Cookies未正确设置或记录
我在运行Pylons应用中的授权单元测试时遇到了一些问题。看起来在测试用例中设置的某些cookie可能没有正确写入或解析。当我用浏览器访问应用时,cookie是正常工作的。
这是我在paste生成的TestController中的测试用例:
def test_good_login(self):
r = self.app.post('/dologin', params={'login': self.user['username'], 'password': self.password})
r = r.follow() # Should only be one redirect to root
assert 'http://localhost/' == r.request.url
assert 'Dashboard' in r
这个测试是为了检查一个已存在账户的登录是否能把用户转到仪表盘页面。结果却是用户被重定向回登录页面。第一次POST请求是成功的,用户信息被存入会话中,并返回了cookie。虽然这些cookie在后续请求中被发送,但似乎没有被正确解析。
我在上述方法的开头设置了一个断点,看看登录响应返回了什么:
> nosetests --pdb --pdb-failure -s foo.tests.functional.test_account:TestMainController.test_good_login
Running setup_config() from foo.websetup
> /Users/istevens/dev/foo/foo/tests/functional/test_account.py(33)test_good_login()
-> r = self.app.post('/dologin', params={'login': self.user['username'], 'password': self.password})
(Pdb) n
> /Users/istevens/dev/foo/foo/tests/functional/test_account.py(34)test_good_login()
-> r = r.follow() # Should only be one redirect to root
(Pdb) p r.cookies_set
{'auth_tkt': '"4c898eb72f7ad38551eb11e1936303374bd871934bd871833d19ad8a79000000!"'}
(Pdb) p r.request.environ['REMOTE_USER']
'4bd871833d19ad8a79000000'
(Pdb) p r.headers['Location']
'http://localhost/?__logins=0'
看起来会话被创建了,并且返回了一个cookie。浏览器被重定向到根目录,而不是登录页面,这也表明登录成功。如果我继续执行follow(),我得到:
> /Users/istevens/dev/foo/foo/tests/functional/test_account.py(35)test_good_login()
-> assert 'http://localhost/' == r.request.url
(Pdb) p r.request.headers
{'Host': 'localhost:80', 'Cookie': 'auth_tkt=""\\"4c898eb72f7ad38551eb11e1936303374bd871934bd871833d19ad8a79000000!\\"""; '}
(Pdb) p r.request.environ['REMOTE_USER']
*** KeyError: KeyError('REMOTE_USER',)
(Pdb) p r.request.environ['HTTP_COOKIE']
'auth_tkt=""\\"4c898eb72f7ad38551eb11e1936303374bd871934bd871833d19ad8a79000000!\\"""; '
(Pdb) p r.request.cookies
{'auth_tkt': ''}
(Pdb) p r
<302 Found text/html location: http://localhost/login?__logins=1&came_from=http%3A%2F%2Flocalhost%2F body='302 Found...y. '/149>
这让我觉得cookie在请求中是传递过来的,虽然转义方式有点可疑。环境中似乎没有之前请求中创建的会话。cookie已经从头部复制到环境中,但请求中的cookie似乎设置不正确。最后,用户被重定向到登录页面,这表明用户并没有登录。
应用中的授权是通过repoze.who和repoze.who.plugins.ldap来完成的,repoze.who_friendlyform负责挑战。我使用的是paste创建的标准tests.TestController
:
class TestController(TestCase):
def __init__(self, *args, **kwargs):
if pylons.test.pylonsapp:
wsgiapp = pylons.test.pylonsapp
else:
wsgiapp = loadapp('config:%s' % config['__file__'])
self.app = TestApp(wsgiapp)
url._push_object(URLGenerator(config['routes.map'], environ))
TestCase.__init__(self, *args, **kwargs)
顺便说一下,这是一个webtest.TestApp
。
cookie的编码是在webtest.TestApp中使用Cookie完成的:
>>> from Cookie import _quote
>>> _quote('"84533cf9f661f97239208fb844a09a6d4bd8552d4bd8550c3d19ad8339000000!"')
'"\\"84533cf9f661f97239208fb844a09a6d4bd8552d4bd8550c3d19ad8339000000!\\""'
我相信这是正确的。
我猜测是响应端的某些东西在将cookie数据解析到服务器端请求中的cookies
时出现了问题。但是什么呢?有没有什么想法?
2 个回答
这个问题在我使用的任何版本的WebTest中都一直存在。不过,经过一番折腾,我发现第一次设置cookie时,REMOTE_ADDR的值是127.0.0.1,但在第二次请求时,它变成了0.0.0.0。
如果我在进行get请求时把REMOTE_ADDR设置为127.0.0.1,一切就正常了!
response = response.goto(url('home'), extra_environ=dict(REMOTE_ADDR='127.0.0.1'))
这个问题在把WebTest的版本从1.2.1降级到1.2之后就消失了。