当前位置:  开发笔记 > 编程语言 > 正文

Flask-restful API授权.访问装饰器内的current_identity

如何解决《Flask-restfulAPI授权.访问装饰器内的current_identity》经验,为你挑选了2个好方法。

我使用flask-restful来创建我的API.我用于flask-jwt启用基于身份验证JWT.现在我需要做授权.

我试过把我的授权装饰器.

test.py(/ test api)

from flask_restful import Resource
from flask_jwt import jwt_required

from authorization_helper import authorized_api_user_type


class Test(Resource):

    decorators = [jwt_required(), authorized_api_user_type()]

    def get(self):
        return 'GET OK'

    def post(self):
        return 'POST OK'

基本上为了处理基本授权,我需要访问current_identity并检查它的类型.然后基于它的类型我将决定用户是否有权访问api/resources.

current_identity似乎是empty那个装饰者.因此,要间接获取它,我必须看到代码jwt_handler并在那里完成工作.

authorization_helper.py

from functools import wraps
from flask_jwt import _jwt, JWTError
import jwt
from models import Teacher, Student

def authorized_api_user_type(realm=None, user_type='teacher'):
    def wrapper(fn):
        @wraps(fn)
        def decorator(*args, **kwargs):
            token = _jwt.request_callback()

            if token is None:
                raise JWTError('Authorization Required', 'Request does not contain an access token',
                               headers={'WWW-Authenticate': 'JWT realm="%s"' % realm})

            try:
                payload = _jwt.jwt_decode_callback(token)
            except jwt.InvalidTokenError as e:
                raise JWTError('Invalid token', str(e))

            identity = _jwt.identity_callback(payload)
            if user_type == 'student' and isinstance(identity, Student):
                return fn(*args, **kwargs)
            elif user_type == 'teacher' and isinstance(identity, Teacher):
                return fn(*args, **kwargs)
            # NOTE - By default JWTError throws 401. We needed 404. Hence status_code=404
            raise JWTError('Unauthorized',
                           'You are unauthorized to request the api or access the resource',
                           status_code=404)
        return decorator
    return wrapper

为什么我不能current_identity在我的authorized_api_user_type装饰师中访问?什么是在烧瓶中进行授权的正确方法?



1> aGuegu..:

这是两者的快速入门的组合Flask-JWTFlask-Restful.

from flask import Flask
from flask_restful import Resource, Api, abort
from functools import wraps

app = Flask(__name__)
api = Api(app)

from flask_jwt import JWT, jwt_required, current_identity
from werkzeug.security import safe_str_cmp

class User(object):
    def __init__(self, id, username, password):
        self.id = id
        self.username = username
        self.password = password

    def __str__(self):
        return "User(id='%s')" % self.id

users = [
    User(1, 'user1', 'abcxyz'),
    User(2, 'user2', 'abcxyz'),
]

username_table = {u.username: u for u in users}
userid_table = {u.id: u for u in users}

def authenticate(username, password):
    user = username_table.get(username, None)
    if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
        return user

def identity(payload):
    user_id = payload['identity']
    return userid_table.get(user_id, None)

app.config['SECRET_KEY'] = 'super-secret'

jwt = JWT(app, authenticate, identity)


def checkuser(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if current_identity.username == 'user1':
            return func(*args, **kwargs)
        return abort(401)
    return wrapper

class HelloWorld(Resource):
    decorators = [checkuser, jwt_required()]
    def get(self):
        return {'hello': current_identity.username}

api.add_resource(HelloWorld, '/')

if __name__ == '__main__':
    app.run(debug=True)

POST

{
    "username": "user1",
    "password": "abcxyz"
}

为了localhost:5000/auth得到access_token回应.

然后localhost:5000/用标题获取

Authorization: JWT `the access_token value above`

你会得到的

{
  "hello": "user1"
}

如果你尝试使用localhost:5000/user2的JWT令牌访问,你会得到401.

装饰器以这种方式包装:

for decorator in self.decorators:
    resource_func = decorator(resource_func)

https://github.com/flask-restful/flask-restful/blob/master/flask_restful/ 初始化的.py#L445

因此,decorators数组中的后一个可以更早地运行.

更多参考:

https://github.com/rchampa/timetable/blob/master/restful/users.py

https://github.com/mattupstate/flask-jwt/issues/37



2> Nikolay Fomi..:

我目前的解决方案如下:

@app.before_request
def detect_something():
    header = request.headers.get('Authorization')
    if header:
        _, token = header.split()
        request.identity = identity(jwt.decode(token,
                                               app.config['SECRET_KEY']))

在它之后,我们可以通过装饰器访问身份request.identity.我current_identity从代码中删除了所有地方.它仍然是凌乱的方式.

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有