flaskjwtextended:测试期间伪造授权头(pytest)

2024-10-01 13:41:22 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我想测试的函数

@jwt_required
    def get_all_projects(self):
        # implementation not included here

我从pytest类调用函数

^{pr2}$

使用db_session夹具

@pytest.fixture(scope='function')
def db_session(db, request):
    """Creates a new database session for a test."""
    engine = create_engine(
                            DefaultConfig.SQLALCHEMY_DATABASE_URI,
                            connect_args={"options": "-c timezone=utc"})
    DbSession = sessionmaker(bind=engine)
    session = DbSession()
    connection = engine.connect()
    transaction = connection.begin()
    options = dict(bind=connection, binds={})
    session = db.create_scoped_session(options=options)
    db.session = session

    yield session

    transaction.rollback()
    connection.close()
    session.remove()

这就导致了错误

>           raise NoAuthorizationError("Missing {} Header".format(header_name))
E           flask_jwt_extended.exceptions.NoAuthorizationError: Missing Authorization Header

../../.virtualenvs/my-app/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py:132: NoAuthorizationError

手动调用create_access_token

当我在上面的fixture中调用create_access_token时,仍然得到相同的结果

db.session = session
session._test_access_token = create_access_token(identity='pytest')

yield session

在使用pytest进行测试期间,我如何伪造JWT令牌?在


Tags: testtokendbaccesspytestsessiondefconnect
3条回答

@jwt_required仅在Flask请求的上下文中有效。您可以使用带有headers name选项的flask test client发送访问令牌:

def test_foo():
    test_client = app.test_client()
    access_token = create_access_token('testuser')
    headers = {
        'Authorization': 'Bearer {}'.format(access_token)
    }
    response = test_client.get('/foo', headers=headers)
    # Rest of test code here

或者,您可以使用__wrapped__属性来展开装饰方法。在您的情况下,它看起来像:

^{pr2}$

注意,对flask jwt的任何调用都扩展了端点中的helper函数(例如get_jwt_identity()current_user等)。不会以这种方式工作,因为它们需要烧瓶请求上下文。您可以通过模拟函数内部使用的flask jwt扩展函数来解决这个问题,但是随着应用程序的增长和变化,这可能更难维护。在

在单元测试期间伪造JWT令牌的一个选项是修补JWT_required。更具体地说,修补底层函数verify_jwt_in_request。这将模拟decorator,并消除为测试创建授权令牌的需要。在

from unittest.mock import patch


@patch('flask_jwt_extended.view_decorators.verify_jwt_in_request')
def test_get_all_projects(mock_jwt_required):
    # ...

这就是我最后要做的,为我工作。在conftest.py公司名称:

@pytest.yield_fixture(scope='function')
def app():
  _app = create_app(TestConfig)
  ctx = _app.test_request_context()
  ctx.push()

  yield _app

  ctx.pop()

@pytest.fixture(scope='function')
def testapp(app):
    """A Webtest app."""
    testapp = TestApp(app)

    with testapp.app.test_request_context():
        access_token = create_access_token(identity=User.query.filter_by(email='test@test.com').first(), expires_delta=False, fresh=True)
    testapp.authorization = ('Bearer', access_token)

    return testapp

然后在TestConfig中,为flask jwt extended设置以下标志:

^{pr2}$

相关问题 更多 >