Я реструктурирую свое приложение, успокаивающее Flask, но у меня возникают проблемы с установкой HTTP-аутентификации для запуска приложения

По сути, у меня есть каталог как таковой:

/app
  runserver.py
  /myapp
    __init__.py
    api.py
    auth.py
    /resources
      __init.py
      users.py
      login.py
    /models
      __init.py
      models.py
    /common
    /assets

В моем auth.py у меня есть стандартная HTTP-аутентификация по имени пользователя и паролю. Я буду использовать их для областей, где необходимо войти в систему, и я хочу проверить каждого пользователя. В Login.py мне нужно добавить свой декоратор, но все приложение не запускается из-за этой ошибки: AttributeError: у объекта 'module' нет атрибута 'login_required'

from flask.ext.httpauth import HTTPBasicAuth
auth = HTTPBasicAuth()

@auth.verify_password
def verify_password(username, password):
    user = User.query.filter_by(username = username).first()
    if not user or not user.verify_password(password):
        return False
    g.user = user
    return True

@auth.error_handler
def unauthorized():
    return make_response(jsonify({'message': 'Unauthorized'}), 403)

Мой код для login.py, который вызывает декоратор, а затем запрашивает аутентификацию.

from flask_restful import Resource, reqparse
from myapp.models.users import User
from myapp import auth 

class login(Resource):
    decorators = [auth.login_required]

    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('userid', type = str , default="")
        self.reqparse.add_argument('username', type = str,  default="")
        self.reqparse.add_argument('password', type = str,  default="")
        super(login, self).__init__()


    def post(self):
        args = self.reqparse.parse_args()
        username = args['username']
        password = args['password']
        message = {'status': 'Authorized'}
    return message

Итак, чтобы закончить, мой вопрос: как и где я могу добавить класс flask-httpauth, чтобы я мог использовать декораторы. Мой вариант сейчас может заключаться в том, чтобы вставить этот код авторизации в каждый класс ресурсов, который в этом нуждается, но, похоже, должен быть лучший способ организовать это. Помогите?

3 ответа

Вы импортируете свой auth модуль, когда вы действительно хотите импортировать HTTPBasicAuth объект в этом модуле. Также возможно, что вы столкнулись с проблемами из-за того, что ваш модуль имеет то же имя, что и HTTPBasicAuth объект.

Я рекомендую переименовать ваш auth.py к чему-то еще, такому как authentication.pyи измените ваш импорт на:

from ..authentication import auth

Извините, это немного устарело, но ради других с этим вопросом я бы посоветовал не использовать flask.ext.httpauth. Я обнаружил, что это не очень полезно. Вот как я выполняю основную аутентификацию HTTP с помощью flask-restful.

Это в myapp /init.py:

from flask import Flask, request
from flask.ext.restful import abort

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth:
            abort(401)
        user = User.query.filter(User.username == auth.username).first()
        auth_ok = False
        if user != None:
            auth_ok = verify_password(auth.password) == user.password
        if not auth_ok:
            return abort(401)
        return f(*args, **kwargs)
    return decorated

Сценарий ресурса, имеющий ресурс, для доступа к которому требуется авторизация.

from myapp import requires_auth

@requires_auth
def get(self):
    # do something

Это немного сбивает с толку, потому что у вас есть auth.py модуль, который определяет auth переменная внутри.

Линия:

from myapp import auth

импортирует модуль, а не переменную, определенную в нем. Измените это на:

from myapp.auth import auth

И я думаю, что это сработает.

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