如何使用 HTTP Basic Auth 注释测试 Flask 路由方法
How to test Flask router methods with HTTPBasicAuth annotations
我是 Python 的新手,我尝试在 Flask 上实现 REST API 服务。我遇到了与代码测试相关的问题。我的 Flask 应用看起来像这样:
from flask import Flask, jsonify, make_response, request
from flask_httpauth import HTTPBasicAuth
import os
auth = HTTPBasicAuth()
@auth.get_password
def get_password(username):
if username == os.environ['SERVICE_KEY']:
return os.environ['SERVICE_PASS']
return None
@auth.error_handler
def unauthorized():
return make_response(jsonify({'error': 'Unauthorized access'}), 403)
app = Flask(__name__)
tweets = [
{
'id': 1,
'profileId': '1',
'message': 'My test tweet'
},
{
'id': 2,
'profileId': '1',
'message': 'Second tweet!'
}
]
@app.route('/api/v1/tweets', methods=['GET'])
@auth.login_required
def get_tweets():
return jsonify({'tweets': tweets}), 200
@app.errorhandler(404)
@auth.login_required
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
if __name__ == '__main__':
app.run(debug=True)
这是我的测试(目前只针对not_found
方法):
import unittest
from app import app
class TestApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
def test_404(self):
rv = self.app.get('/i-am-not-found')
self.assertEqual(rv.status_code, 404)
if __name__ == '__main__':
unittest.main()
但是当我尝试 运行 测试时,它失败了,因为我得到 'Unauthorized access' 响应:
>python test.py
F
======================================================================
FAIL: test_404 (__main__.TestApp)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test.py", line 25, in test_404
self.assertEqual(rv.status_code, 404)
AssertionError: 403 != 404
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
哪种测试路由方法的方法更适合处理授权?我该如何修复失败的测试?
您需要创建一个包含您的身份验证详细信息的自定义 header,并将其与您的请求一起发送。像这样:
from base64 import b64encode
...
headers = {'Authorization': 'Basic ' + b64encode("{0}:{1}".format(username, password))}
rv = self.app.get('/i-am-not-found', headers=headers)
...
import unittest
from app import app
class TestApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
def test_404(self):
headers = {
'Authorization': 'Basic ' + b64encode("username:password")
}
rv = self.app.get('/i-am-not-found', headers=headers)
self.assertEqual(rv.status_code, 404)
if __name__ == '__main__':
unittest.main()
您的用户名和密码以 username:password
形式发送,但采用 base64 编码。如果扩展它,有一些方法可以使它更简单,例如提取到一个函数中以始终传递 header 并外部化 username/password 进行测试。
编辑:此外,我认为您应该在此处返回 401 代码。 401 通常在凭据不正确时使用,403 通常在您成功验证自己但无权访问资源时使用。一个非常简单的例子,登录到 Facebook 但被限制访问另一个人标记为私人的照片。
我是 Python 的新手,我尝试在 Flask 上实现 REST API 服务。我遇到了与代码测试相关的问题。我的 Flask 应用看起来像这样:
from flask import Flask, jsonify, make_response, request
from flask_httpauth import HTTPBasicAuth
import os
auth = HTTPBasicAuth()
@auth.get_password
def get_password(username):
if username == os.environ['SERVICE_KEY']:
return os.environ['SERVICE_PASS']
return None
@auth.error_handler
def unauthorized():
return make_response(jsonify({'error': 'Unauthorized access'}), 403)
app = Flask(__name__)
tweets = [
{
'id': 1,
'profileId': '1',
'message': 'My test tweet'
},
{
'id': 2,
'profileId': '1',
'message': 'Second tweet!'
}
]
@app.route('/api/v1/tweets', methods=['GET'])
@auth.login_required
def get_tweets():
return jsonify({'tweets': tweets}), 200
@app.errorhandler(404)
@auth.login_required
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
if __name__ == '__main__':
app.run(debug=True)
这是我的测试(目前只针对not_found
方法):
import unittest
from app import app
class TestApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
def test_404(self):
rv = self.app.get('/i-am-not-found')
self.assertEqual(rv.status_code, 404)
if __name__ == '__main__':
unittest.main()
但是当我尝试 运行 测试时,它失败了,因为我得到 'Unauthorized access' 响应:
>python test.py F ====================================================================== FAIL: test_404 (__main__.TestApp) ---------------------------------------------------------------------- Traceback (most recent call last): File "test.py", line 25, in test_404 self.assertEqual(rv.status_code, 404) AssertionError: 403 != 404 ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (failures=1)
哪种测试路由方法的方法更适合处理授权?我该如何修复失败的测试?
您需要创建一个包含您的身份验证详细信息的自定义 header,并将其与您的请求一起发送。像这样:
from base64 import b64encode
...
headers = {'Authorization': 'Basic ' + b64encode("{0}:{1}".format(username, password))}
rv = self.app.get('/i-am-not-found', headers=headers)
...
import unittest
from app import app
class TestApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
def test_404(self):
headers = {
'Authorization': 'Basic ' + b64encode("username:password")
}
rv = self.app.get('/i-am-not-found', headers=headers)
self.assertEqual(rv.status_code, 404)
if __name__ == '__main__':
unittest.main()
您的用户名和密码以 username:password
形式发送,但采用 base64 编码。如果扩展它,有一些方法可以使它更简单,例如提取到一个函数中以始终传递 header 并外部化 username/password 进行测试。
编辑:此外,我认为您应该在此处返回 401 代码。 401 通常在凭据不正确时使用,403 通常在您成功验证自己但无权访问资源时使用。一个非常简单的例子,登录到 Facebook 但被限制访问另一个人标记为私人的照片。