10

这是我在 Flask-RESTful 中的单元测试的一部分。

self.app = application.app.test_client()
rv = self.app.get('api/v1.0/{0}'.format(ios_sync_timestamp))
eq_(rv.status_code,200)

在命令行中,我可以使用 curl 将用户名:密码发送到服务:

curl -d username:password http://localhost:5000/api/v1.0/1234567

如何在单元测试的 get() 中实现相同的目标?

由于我的 get/put/post 需要身份验证,否则测试将失败。

4

3 回答 3

16

来自RFC 1945,超文本传输​​协议 -- HTTP/1.0

11.1 基本认证方案

...

为了接收授权,客户端发送用户 ID 和密码,由单个冒号 (":") 字符分隔,在凭据字符串中的 base64 [5] 编码字符串中。

...

如果用户代理希望发送用户 ID“Aladdin”和密码“open sesame”,它将使用以下标头字段:

  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

因此,如果您真的使用 http 基本身份验证,您可以像下面这样解决,尽管您的curl使用建议了其他一些身份验证方案。

from base64 import b64encode

headers = {
    'Authorization': 'Basic ' + b64encode("{0}:{1}".format(username, password)).decode('utf-8')
}

rv = self.app.get('api/v1.0/{0}'.format(ios_sync_timestamp), headers=headers)
于 2013-10-22T21:57:18.670 回答
2

另一种解决方案 - 所有功劳归于 Doug Black

def request(self, method, url, auth=None, **kwargs):
    headers = kwargs.get('headers', {})
    if auth:
        headers['Authorization'] = 'Basic ' + base64.b64encode(auth[0] + ':' + auth[1])

    kwargs['headers'] = headers

    return self.app.open(url, method=method, **kwargs)

然后在你的测试中使用这个方法:

resp = self.request('GET', 'api/v1.0/{0}'.format(ios_sync_timestamp), auth=(username, password))
于 2013-10-23T09:14:34.027 回答
2

对于 Python 3,请尝试以下示例:

from base64 import b64encode
headers = {
    'Authorization': 'Basic %s' % b64encode(b"username:password").decode("ascii")
}

self.app.get("foo/", headers=headers)

如果您想对用户名和密码使用动态变量,请尝试以下操作:

'Basic %s' % b64encode(bytes(username + ':' + password, "utf-8")).decode("ascii")

另请参阅:Python、带有基本身份验证的 HTTPS GET

于 2015-05-03T14:10:06.783 回答