首页 > 解决方案 > 装饰器不将对象返回给 get 方法

问题描述

我编写了一个带有两个端点的小型 falsk-restpluss API:/login 和 /users。

它具有 jwt 身份验证,并且该部分工作正常。

检查令牌的装饰器还从数据库中获取当前用户对象并将其发送回 get 函数。

对我来说,装饰器似乎没有将对象返回给 get 函数,我不知道为什么。

非常感谢任何帮助!

我收到此错误:

if not current_user.admin:
AttributeError: 'Users' object has no attribute 'admin'

我正在使用烧瓶-restplus 和 python 3.7

这是我的代码:

import ....
(Import left out) 

app = Flask(__name__)
app.config.SWAGGER_UI_DOC_EXPANSION = 'full'

authorizations = {
    'apikey' : {
        'type' : 'apiKey',
        'in' : 'header',
        'name' : 'X-API-KEY'
    }
}

db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ....
    (Rest of the definitions is left out.)

def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        if 'X-API-KEY' in request.headers:
            token = request.headers['X-API-KEY']

        if not token:
            return {'message' : 'Token is missing!'}, 401
        try:
            data = jwt.decode(token, app.config['SECRET_KEY'])
            current_user = User.query.filter_by(public_id=data['public_id']).first()

        except:
            return {'message' : 'Token is invalid!'}, 401

        return f(current_user, *args, **kwargs)
    return decorated

@api.route('/user')
class Users(Resource):
    @token_required
    @api.doc(security='apikey')

    def get(self,current_user):
        if not current_user.admin:
            return {'message' : 'Cannot perform that function!'}

        return {'users' : 'List of users to come.'}

@api.route('/login')
class Login(Resource):
    def get(self):
        auth = request.authorization

        if not auth or not auth.username or not auth.password:
            return make_response('No user credits are entered', 401, {'WWW-Authenticate' : 'Basic realm="Login required!"'})

        user = User.query.filter_by(name=auth.username).first()

        if not user:
            return make_response('user is empty', 401, {'WWW-Authenticate' : 'Basic realm="Login required!"'})

        token = jwt.encode({'public_id' : user.public_id, 'exp' : datetime.now() + timedelta(minutes=30)}, app.config['SECRET_KEY'])

        if check_password_hash(user.password, auth.password):
            token = jwt.encode({'public_id' : user.public_id, 'exp' : datetime.now() + timedelta(minutes=30)}, app.config['SECRET_KEY'])
            return {'token' : token.decode('UTF-8')}

        return make_response('User not hashed', 401, {'WWW-Authenticate' : 'Basic realm="Login required!"'})

标签: pythonflask-sqlalchemyflask-restful

解决方案


你需要接受并传递self论点。

@wraps(f)
def decorated(self, *args, **kwargs):
    ...
    return f(self, current_user, *args, **kwargs)

推荐阅读