Pylons 应用程序中的单元测试授权失败; cookie 未正确设置或记录

发布于 2024-08-31 03:55:18 字数 3251 浏览 2 评论 0原文

我在 Pylons 应用程序中运行授权单元测试时遇到问题。似乎测试用例中设置的某些 cookie 可能无法正确写入或解析。当使用浏览器访问应用程序时,Cookie 可以正常工作。

这是我在粘贴生成的 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。浏览器重定向到root,而不是登录,这也说明登录成功。如果我跳过 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 执行质询。我正在使用通过粘贴创建的库存 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 数据解析为服务器端请求中的 cookie 。但什么?有什么想法吗?

I'm having an issue running unit tests for authorization in a Pylons app. It appears as though certain cookies set in the test case may not be correctly written or parsed. Cookies work fine when hitting the app with a browser.

Here is my test case inside a paste-generated 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

This is supposed to test that a login of an existing account forwards the user to the dashboard page. Instead, what happens is that the user is redirected back to the login. The first POST works, sets the user in the session and returns cookies. Although those cookies are sent in the follow request, they don't seem to be correctly parsed.

I start by setting a breakpoint at the beginning of the above method and see what the login response returns:

> 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'

A session appears to be created and a cookie sent back. The browser is redirected to the root, not the login, which also indicates a successful login. If I step past the follow(), I get:

> /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>

This indicates to me that the cookie was passed in on the request, although with dubious escaping. The environ appears to be without the session created on the prior request. The cookie has been copied to the environ from the headers, but the cookies in the request seems incorrectly set. Lastly, the user is redirected to the login page, indicating that the user isn't logged in.

Authorization in the app is done via repoze.who and repoze.who.plugins.ldap with repoze.who_friendlyform performing the challenge. I'm using the stock tests.TestController created by paste:

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)

That's a webtest.TestApp, by the way.

The encoding of the cookie is done in webtest.TestApp using Cookie:

>>> from Cookie import _quote
>>> _quote('"84533cf9f661f97239208fb844a09a6d4bd8552d4bd8550c3d19ad8339000000!"')
'"\\"84533cf9f661f97239208fb844a09a6d4bd8552d4bd8550c3d19ad8339000000!\\""'

I trust that that's correct.

My guess is that something on the response side is incorrectly parsing the cookie data into cookies in the server-side request. But what? Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

信愁 2024-09-07 03:55:18

将 WebTest 从 1.2.1 降级到 1.2 后,此问题消失。

This issue disappeared after downgrading WebTest from 1.2.1 to 1.2.

傾城如夢未必闌珊 2024-09-07 03:55:18

无论 WebTest 的版本如何,这个问题都不断地出现在我身上。然而,经过一番研究后,我注意到第一次设置 cookie 时,它​​使用 127.0.0.1 作为 REMOTE_ADDR 值,但在第二次请求时,它更改为 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'))

The issue continually appeared for me regardless of the version of WebTest. However, after much mucking around I noticed that when the cookie was first set it was using 127.0.0.1 as the REMOTE_ADDR value but on the second request it changed to 0.0.0.0.

If I did the get request and set the REMOTE_ADDR to 127.0.0.1 all was well!

response = response.goto(url('home'), extra_environ=dict(REMOTE_ADDR='127.0.0.1'))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文