Flask аутентификация декораторов

В настоящее время я использую два типа аутентификации в моем API:

  • Локальный пользователь + локальный пароль
  • Пользователь БД + пароль БД

Для этого я хочу определить декоратор для каждого типа. Пример:

@authenticator.local_authentication

или же

@authenticator.db_authentication

В настоящее время у меня есть рабочая версия аутентификатора локальной аутентификации. Я хочу создать один для @authenticator.db_authentication, Я использую пост Мигеля в качестве ссылки, чтобы добавить поддержку аутентификации БД.

Пример в настоящее время работает с HTTPBasicAuth,

Кажется, мне нужно переписать auth.login_required а также auth.verify_password которые должны быть определены при использовании: @auth.login_required обрабатывать аутентификацию.

В идеале я хочу определить что-то подобное в моих методах API:

@authenticator.db_authentication
def get(self):
 ...

Это рабочий код, который требует модификации:

from flask_httpauth import HTTPBasicAuth
auth = HTTPBasicAuth()

@auth.verify_password
def verify_password(username_or_token, password):
    """Validates username or password in database.

    :param username_or_token:
    :param password:
    :return: user
    """
    return authenticator.db_authentication(username_or_token, password)

class Status(Resource):
    """Used for verifying API status"""

    @auth.login_required
    def get(self):
        """

        :return:
        """
        log.info(request.remote_addr + ' ' + request.__repr__())
        log.info('api() | GET | Received request for Status')
        response = json.dumps('Status: Hello %s!' % g.user.username)
        return Response(response, status=200, mimetype=settings.api_mime_type)

    @authenticator.local_authentication
    def post(self):
        log.info(request.remote_addr + ' ' + request.__repr__())
        log.info('api() | POST | Received request for Status')
        response = json.dumps('Status: POST. %s' % settings.api_ok)
        return Response(response, status=202, mimetype=settings.api_mime_type)

я хочу измениться @auth.login_required в @authenticator.db_authentication

Пример @authenticator.local_authentication в другом файле ниже:

def check_auth(username, password):
    """ Basic authentication: local username and password.

    :param username:
    :param password:
    :return:
    """
    return username == settings.api_account and password == settings.api_password


def authentication_error():
    """
    Authentication error.
    :return:
    """

    response = jsonify({'message': "Authenticate."})
    response.headers['WWW-Authenticate'] = settings.api_realm
    response.status_code = 401
    return response


def local_authentication(f):
    """Decorator to check local authentication.
    :param f: A function
    :return: itself: Decorator check_credentials
    """

    @wraps(f)
    def check_credentials(*args, **kwargs):
        auth = request.authorization
        if not auth:
            return authentication_error()

        elif not check_auth(auth.username, auth.password):
            return authentication_error()
        return f(*args, **kwargs)

    return check_credentials

def db_authentication(username_or_token, password):
    """First try to authenticate by token.

    :param username_or_token:
    :param password:
    :return: boolean
    """

    user = Model.ApiUsers.verify_auth_token(username_or_token)
    if not user:
        # Try to authenticate with database password.
        user = Model.ApiUsers.query.filter_by(username=username_or_token).first()
        if not user or not user.verify_password(password):
            return False
    g.user = user
    return True

0 ответов

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