You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask添加基于角色的访问装饰器时出现NameError问题求助

问题分析与修复方案

问题根源

  • 装饰器执行顺序错误:Python装饰器是从下往上应用的,你写的@token_required在@admin_required上方,实际会先执行admin_required的权限检查,再执行token_required的用户认证。但权限检查需要current_user,此时current_user还未被认证生成,自然找不到。
  • 参数传递问题:token_required会把current_user作为参数传给后续函数,但permission_required的装饰器函数没有接收这个参数,直接引用current_user变量,导致作用域错误。

修复方案

方案一:调整装饰器顺序+修改权限装饰器接收参数

  1. 调换装饰器顺序:让token_required先执行(放在下方),确保用户认证完成后再做权限检查:
@auth.route('/testing', methods=['GET'])
@admin_required
@token_required  # 先执行token_required注入current_user,再执行admin_required检查权限
def testing(current_user):
    print(current_user.can(Permission.ADMIN))
    return "successful"
  1. 修改permission_required装饰器:让它接收current_user参数,确保能拿到用户对象:
def permission_required(permission):
    def decorator(f):
        @wraps(f)
        def decorated_function(current_user, *args, **kwargs):
            if not current_user.can(permission):
                return jsonify({'message' : 'You dont have right permission!'}), 401
            return f(current_user, *args, **kwargs)
        return decorated_function
    return decorator

方案二:使用Flask全局请求对象存储用户(更优雅)

如果你的项目基于Flask,推荐用全局g对象存储current_user,避免参数传递的麻烦:

  1. 修改token_required:将查询到的用户存入Flask全局g对象:
from flask import g

def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        if 'x-access-token' in request.headers:
            token = request.headers['x-access-token']
        if not token:
            return jsonify({'message' : 'Token is missing !!'}), 401
        try:
            data = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=["HS256"])
            current_user = db_session.query(Account).filter_by(public_id=data['public_id']).first()
            g.current_user = current_user  # 存入全局对象
        except:
            return jsonify({
                'message' : 'Token is invalid !!'
            }), 401
        return f(*args, **kwargs)
    return decorated
  1. 修改permission_required:从全局g对象中获取用户:
from flask import g

def permission_required(permission):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            current_user = g.current_user
            if not current_user.can(permission):
                return jsonify({'message' : 'You dont have right permission!'}), 401
            return f(*args, **kwargs)
        return decorated_function
    return decorator
  1. 简化测试函数:不需要再接收current_user参数:
@auth.route('/testing', methods=['GET'])
@token_required
@admin_required
def testing():
    print(g.current_user.can(Permission.ADMIN))
    return "successful"

内容的提问来源于stack exchange,提问作者ussrback

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:39:34