Аргумент query_client отсутствует в AuthorizationServer

Я определил query_client в ленивой инициализации моего AuthorizationServer как сказано здесь, но это не работает: query_client является None еще.
Вот мой модуль oauth:

from authlib.common.security import generate_token
from authlib.flask.oauth2 import AuthorizationServer, ResourceProtector
from authlib.flask.oauth2.sqla import create_revocation_endpoint, create_bearer_token_validator
from authlib.specs.rfc6749 import grants, OAuth2Token
from flask import session

from website.models import Client, Token, db, User, AuthorizationCode

server = AuthorizationServer()
require_oauth = ResourceProtector()


class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
    def create_authorization_code(self, client, grant_user, request):
        # you can use other method to generate this code
        code = generate_token(48)
        item = AuthorizationCode(
            code=code,
            client_id=client.client_id,
            redirect_uri=request.redirect_uri,
            scope=request.scope,
            user_id=grant_user.get_user_id(),
        )
        db.session.add(item)
        db.session.commit()
        return code

    def parse_authorization_code(self, code, client):
        item = AuthorizationCode.query.filter_by(code=code, client_id=client.client_id)\
            .first()
        if item and not item.is_expired():
            return item

    def delete_authorization_code(self, authorization_code):
        db.session.delete(authorization_code)
        db.session.commit()

    def authenticate_user(self, authorization_code):
        return User.query.get(authorization_code.user_id)


class PasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
    def authenticate_user(self, email, password):
        user = User.query.filter_by(email=email).first()
        if user.check_password(password):
            return user


class RefreshTokenGrant(grants.RefreshTokenGrant):
    def authenticate_refresh_token(self, refresh_token):
        item = OAuth2Token.query.filter_by(refresh_token=refresh_token).first()
        if item and not item.is_refresh_token_expired():
            return item

    def authenticate_user(self, credential):
        return User.query.get(credential.user_id)


def current_user():
    if 'id' in session:
        uid = session['id']
        return User.query.get(uid)
    return None


def query_client(client_id):
    return Client.query.filter_by(client_id=client_id).first()


def save_token(token, request):
    if request.user:
        user_id = request.user.get_user_id()
    else:
        # client_credentials grant_type
        user_id = request.client.user_id
    item = Token(
        client_id=request.client.client_id,
        user_id=user_id,
        **token
    )
    db.session.add(item)
    db.session.commit()


def init_oauth2(app):
    server.init_app(app, query_client=query_client, save_token=save_token)
    # register it to grant endpoint
    server.register_grant(grants.ImplicitGrant)
    server.register_grant(AuthorizationCodeGrant)
    server.register_grant(grants.ClientCredentialsGrant)
    server.register_grant(PasswordGrant)
    server.register_grant(RefreshTokenGrant)
    # support revocation
    revocation_cls = create_revocation_endpoint(db.session, OAuth2Token)
    server.register_endpoint(revocation_cls)
    # protect resource
    bearer_cls = create_bearer_token_validator(db.session, OAuth2Token)
    require_oauth.register_token_validator(bearer_cls())

По запросу oauth/token Я получаю ошибку:

Traceback (most recent call last):
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ghostman/Projects/vistory/auth/website/routes.py", line 124, in issue_token
    return server.create_token_response()
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/flask/oauth2/authorization_server.py", line 251, in create_token_response
    AuthorizationServer, self).create_token_response(req)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/authorization_server.py", line 162, in create_token_response
    grant.validate_token_request()
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/grants/authorization_code.py", line 233, in validate_token_request
    client = self.authenticate_token_endpoint_client()
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/grants/base.py", line 76, in authenticate_token_endpoint_client
    self.TOKEN_ENDPOINT_AUTH_METHODS
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/authenticate_client.py", line 51, in __call__
    return self.authenticate(request, methods)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/authenticate_client.py", line 42, in authenticate
    client = func(self.query_client, request)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/authenticate_client.py", line 60, in authenticate_client_secret_basic
    client = _validate_client(query_client, client_id, request.state, 401)
  File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/authlib/specs/rfc6749/authenticate_client.py", line 120, in _validate_client
    client = query_client(client_id)
TypeError: 'NoneType' object is not callable

Я проверил в отладчике query_client=None даже после ленивой инициализации.

Что я делаю неправильно?

ДОБАВЛЕНО:
Маршрут должен получить токен:

@bp.route('/oauth/token', methods=['POST'])
def issue_token():
    return server.create_token_response()

0 ответов

Другие вопросы по тегам