flask9:API权限控制

1.增加配置信息

# 密钥
SECRET_KEY = '\x88D\xf09\x91\x07\x98\x89\x87\x96\xa0A\xc68\xf9\xecJ:U\x17\xc5V\xbe\x8b\xef\xd7\xd8\xd3\xe6\x98*4'


# token 超时时长
TOKEN_EXPIRATION = 30 * 24 * 3600

2.在USER类中定义验证用户身份的方法

    @staticmethod
    def verify(account, password):
        user = User.query.filter_by(account=account).first_or_404()
        if not user.check_password(password):
            raise AuthFailed()

        scope = {
            "allow": user.get_allow_resources(),
            "forbidden": user.get_forbidden_resources()
        }

        return json.dumps(scope)

    def check_password(self, raw):
        if not self._password:
            return False
        return check_password_hash(self._password, raw)

3.生成令牌

# 生成令牌的程序
def generate_auth_token(uid, ac_type, scope=None,
                        expiration=7200):
    """生成令牌"""
    s = Serializer(current_app.config['SECRET_KEY'],
                   expires_in=expiration)
    return s.dumps({
        'uid': uid,
        'type': ac_type.value,
        'scope': scope
    })


# 验证用户身份并生成令牌
@api.route('', methods=['POST'])
def get_token():
    form = ClientForm().validate_for_api()
    # 验证用户名密码
    scope = User.verify(form.account.data, form.password.data)

    # s_dict = json.loads(scope)

    # 获取有效期配置
    expiration = current_app.config['TOKEN_EXPIRATION']
    # 生成Token
    token = generate_auth_token(form.account.data,
                                form.type.data,
                                scope,
                                expiration)
    t = {
        'token': token.decode('ascii')
    }
    return jsonify(t), 201

4.调用服务认证用户身份并生成令牌

flask9:API权限控制_第1张图片

5.实现验证装饰器的验证方法



auth = HTTPBasicAuth()
User = namedtuple('User', ['uid', 'ac_type', 'scope'])


@auth.verify_password
def verify_password(token, password):

    user_info = verify_auth_token(token)
    if not user_info:
        return False
    else:
        # request
        g.user = user_info
        return True


# 验证token
def verify_auth_token(token):
    s = Serializer(current_app.config['SECRET_KEY'])
    try:
        data = s.loads(token)
    except BadSignature:
        raise AuthFailed(msg='非法令牌!',
                         error_code=1002)
    except SignatureExpired:
        raise AuthFailed(msg='令牌超时!',
                         error_code=1003)
    uid = data['uid']
    ac_type = data['type']
    scope = data['scope']
    # request 视图函数
    allow = is_in_scope(scope, request.endpoint)
    if not allow:
        raise Forbidden()
    return User(uid, ac_type, scope)


# 判断用户是否超权
def is_in_scope(scope, endpoint):

    scope = json.loads(scope)
    allow = scope["allow"]
    forbidden = scope["forbidden"]
    splits = endpoint.split('+')
    red_name = splits[0]
    if red_name in forbidden:
        return False
    if endpoint in forbidden:
        return False
    if endpoint in allow:
        return True
    if red_name in allow:
        return True
    else:
        return False

6.在需要进行权限控制的方法上增加装饰器


# 查询组
@api.route('/', methods=['GET'])
@auth.login_required
def get_group_by_id(id):
    group = Group.get_by_id(id)
    return jsonify(group)


# 调用方式 http://127.0.0.1:5000/admin/group/name?name=电信维护中心
@api.route('/name')
@auth.login_required
def get_group_by_name():
    v_name = request.args.get("name")
    group = Group.get_by_name(v_name)
    return jsonify(group)

7.测试

flask9:API权限控制_第2张图片

flask9:API权限控制_第3张图片

你可能感兴趣的:(python)