2 回答

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超21個(gè)贊
這里只是一個(gè)例子。我跳過了一些小東西,例如create_app,jwt.decode(token)等等。我相信你能理解主要方法。結(jié)構(gòu):
src
├── __init__.py # empty
├── app.py
└── auth_example.py
應(yīng)用程序.py:
from flask import Flask
from src.auth_example import current_identity, authorize
app = Flask(__name__)
@app.route('/')
@authorize()
def main():
"""
You can use flask_restful - doesn't matter
Do here all what you need:
user = User.query.filter_by(id=int(current_identity['user_id'])).first()
etc..
just demo - return current user_id
"""
return current_identity['user_id']
auth_example.py :
from flask import request, _request_ctx_stack
from functools import wraps
from werkzeug.local import LocalProxy
current_identity = LocalProxy(lambda: getattr(_request_ctx_stack.top, 'current_identity', None))
def jwt_decode_handler(token):
"""
just do here all what you need. Should return current user data
:param str token:
:return: dict
"""
# return jwt.decode(token), but now - just demo
raise Exception('just demo')
def authorize():
def _authorize(f):
@wraps(f)
def __authorize(*args, **kwargs):
if 'Authorization' not in request.headers:
return "Unable to log in with provided credentials.", 403
raw_token = request.headers.get('Authorization')
if raw_token[0:3] != 'JWT':
return "Unable to log in with provided credentials.", 403
token = str.replace(str(raw_token), 'JWT ', '')
try:
# I don't know do you use Flask-JWT or not
# this is doesn't matter - all what you need is just to mock jwt_decode_handler result
_request_ctx_stack.top.current_identity = jwt_decode_handler(token)
except Exception:
return "Unable to log in with provided credentials.", 403
return f(*args, **kwargs)
return __authorize
return _authorize
我們的測試:
import unittest
from mock import patch
from src.app import app
app.app_context().push()
class TestExample(unittest.TestCase):
def test_main_403(self):
# just a demo that @authorize works fine
result = app.test_client().get('/')
self.assertEqual(result.status_code, 403)
def test_main_ok(self):
expected = '1'
# we say that jwt_decode_handler will return {'user_id': '1'}
patcher = patch('src.auth_example.jwt_decode_handler', return_value={'user_id': expected})
patcher.start()
result = app.test_client().get(
'/',
# send a header to skip errors in the __authorize
headers={
'Authorization': 'JWT=blabla',
},
)
# as you can see current_identity['user_id'] is '1' (so, it was mocked in view)
self.assertEqual(result.data, expected)
patcher.stop()
因此,在您的情況下,您只需要 mock jwt_decode_handler。另外我建議不要在裝飾器中添加任何額外的參數(shù)。當(dāng)您有兩個(gè)以上具有不同參數(shù)、遞歸、硬處理等的裝飾器時(shí),將很難調(diào)試。
希望這可以幫助。

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊
您能否在您的單元測試框架中創(chuàng)建一些模擬令牌(您的裝飾器實(shí)際上可以像在真實(shí)請求中一樣解碼)并將它們與您的測試客戶端一起發(fā)送?可以在此處查看其外觀示例:https : //github.com/vimalloc/flask-jwt-extended/blob/master/tests/test_view_decorators.py#L321
添加回答
舉報(bào)