如何将用户名:密码发送到unittest的app.get()请求?

时间:2013-10-22 17:03:21

标签: python unit-testing flask http-basic-authentication flask-restful

这是我在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需要验证,否则测试将失败。

3 个答案:

答案 0 :(得分:16)

来自RFC 1945, Hypertext Transfer Protocol -- HTTP/1.0

  

11.1 Basic Authentication Scheme

     

...

     

要获得授权,客户端会发送用户ID和密码,   在base64 [5]内用单个冒号(“:”)字符分隔   在credentials.string中编码的字符串。

     

...

     

如果用户代理希望发送用户ID“Aladdin”和密码   打开芝麻“,它将使用以下标题字段:

  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

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

from base64 import b64encode

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

rv = self.app.get('api/v1.0/{0}'.format(ios_sync_timestamp), headers=headers)

答案 1 :(得分: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))

答案 2 :(得分: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 with basic authentication