首页 > 解决方案 > 在 GET 请求后发送 POST 请求时,Flask 视图函数丢失请求参数

问题描述

此视图在发出 GET 请求时接收 ?next= 参数,但一旦用户向同一视图发出 POST 请求,该参数就会丢失。我看到的示例没有明确传递查询参数,但似乎能够保留它们并在以下 POST 请求中获取它们。

@blueprint.route("/login", methods=["GET", "POST"])
@logout_required()
def login():
    form = LoginForm()
    #1
    print("NEXT:", request.args.get("next"))

    if form.validate_on_submit():
        u = User.query.filter_by(username=form.username.data).first()
        if u and u.check_password(password=form.password.data):
            if u.is_active():
                #2
                print("NEXT:", request.args.get("next"))

                login_user(u, remember=form.remember.data)

                next_url = request.args.get("next")
                if not next_url or url_parse(next_url).netloc != "":
                    next_url = url_for("main.index")

                return redirect(next_url)
            else:
                flash("This account has been disabled", "error")
        else:
            flash("Invalid password or username.", "error")

    return render_template("auth/login.html", form=form)

标签: pythonhttpflaskflask-login

解决方案


return redirect()在最后两个flash()函数之后,您缺少两个重定向,请参见下面的代码:

@blueprint.route("/login", methods=["GET", "POST"])
@logout_required()
def login():
    form = LoginForm()
    #1
    print("NEXT:", request.args.get("next"))

    if form.validate_on_submit():

        next_url = request.args.get("next")  #  -- HERE -- get "?next argument"

        u = User.query.filter_by(username=form.username.data).first()
        if u and u.check_password(password=form.password.data):
            if u.is_active():
                #2
                print("NEXT:", request.args.get("next"))

                login_user(u, remember=form.remember.data)

                # next_url = request.args.get("next")  # -- HERE -- 
                if not next_url or url_parse(next_url).netloc != "":
                    next_url = url_for("main.index")

                return redirect(next_url)

            else:
                flash("This account has been disabled", "error")
                return redirect(url_for('auth.index'))  # -- HERE --

        else:
            flash("Invalid password or username.", "error")
            return redirect(url_for('auth.login', next=next_url))  # -- HERE --

    return render_template("auth/login.html", form=form)

我假设/main是受保护的路由并且当前没有会话,用户还没有登录,所以当用户尝试直接访问时

http://localhost:5000/admin

他将被自动重定向到这个urlauth.login带有参数的路由?next=%2Fadmin%2F

http://localhost:5000/auth/login?next=%2Fadmin%2F

使用默认flask-login flash()消息Please log in to access this page.然后他可以登录,如果登录成功,他将登录并使用?next参数重定向到保护区,

但如果它发生并且诱惑失败了,我们有两个选择:

  • 如果Invalid password or username他将被重定向auth.login路线 ?next=%2Fadmin%2F第二次机会的论点。

  • 但是,如果This account has been disabled他将在没有auth.login参数的情况下重定向路线,那确实是有道理的。 ?next=%2Fadmin%2F

最后你不必担心它的价值,?next=因为用户可以玩它甚至删除它和这个块

                if not next_url or url_parse(next_url).netloc != "":
                    next_url = url_for("main.index")

                return redirect(next_url)

默认为main.index如果有的话。


推荐阅读