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

Flask添加token_required装饰器后出现TypeError参数冲突问题求助

问题与分析

问题场景

开发多语言教育软件的Flask RESTful API时,遇到参数传递冲突错误:

  • 未加装饰器的路由(正常运行):
@lessons_bp.route("/banner/<lang>", methods=["GET"])
def get_banner(lang):
  • 添加token_required装饰器后触发报错:
@lessons_bp.route("/banner/<lang>", methods=["GET"])
@token_required
def get_banner(lang):
  • 报错信息:TypeError: get_banner() got multiple values for argument 'lang'
  • 临时规避方案:给函数增加一个dummy参数改为def get_banner(self, lang):后恢复正常。

装饰器代码

def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        if "Authorization" in request.headers:
            token = request.headers["Authorization"]
        if not token:
            return make_response(
                {"message":"Access token required!"},
                401
                )
        try:
            data = jwt.decode(token, JWT_SECRET_KEY, ALGORITHM)
            current_user = User.query.filter_by(UserId = data["id"]).first()
        except Exception as e:
            print(e)
            return make_response(
                {
                    "message": "Unable to verify token!"
                },
                401
            )
        return f(current_user, *args, **kwargs)
    return decorated

错误原因

Flask处理路由参数时,会把<lang>以关键字参数(即lang=xxx)的形式传入视图函数。而你的装饰器在调用原函数时,先传入current_user作为位置参数,再传递*args(此处为空)和**kwargs(包含lang的键值对)。

当视图函数定义为def get_banner(lang):时,装饰器的调用逻辑等价于get_banner(current_user, lang=xxx)——此时lang既被位置参数current_user占用,又通过关键字参数传入,直接导致参数重复赋值,触发got multiple values错误。

改成def get_banner(self, lang):时,current_user会被赋值给self参数,lang通过关键字参数正常接收,参数不再冲突,因此报错消失。

解决方案

有两种规范的修正方式:

方式1:调整视图函数签名

让视图函数直接接收current_user位置参数:

@lessons_bp.route("/banner/<lang>", methods=["GET"])
@token_required
def get_banner(current_user, lang):
    # 业务逻辑代码

方式2:修改装饰器传参方式

将current_user以关键字参数形式传入原函数,避免位置参数冲突:
修改装饰器中调用原函数的代码:

# 原代码:return f(current_user, *args, **kwargs)
return f(*args, current_user=current_user, **kwargs)

对应的视图函数需要定义关键字参数(可设为可选参数,提升装饰器通用性):

def get_banner(lang, current_user=None):
    # 业务逻辑代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:06:11