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