如何使用 Flask 和 Flask-login 传递“下一个”URL?

2024-01-05

的文档Flask 登录 https://flask-login.readthedocs.org/en/latest/谈论处理“下一个”URL。这个想法似乎是:

  1. 用户前往/secret
  2. 用户被重定向到登录页面(例如/login)
  3. 登录成功后,用户将被重定向回/secret

我发现的唯一使用 Flask-login 的半完整示例是https://gist.github.com/bkdinoop/6698956 https://gist.github.com/bkdinoop/6698956。它很有帮助,但由于它不包含 HTML 模板文件,我想看看是否可以重新创建它们作为自我训练练习。

这是一个简化版本/secret and /login部分:

@app.route("/secret")
@fresh_login_required
def secret():
    return render_template("secret.html")

@app.route("/login", methods=["GET", "POST"])
def login():
    <...login-checking code omitted...>
    if user_is_logged_in:
        flash("Logged in!")
        return redirect(request.args.get("next") or url_for("index"))
    else:
        flash("Sorry, but you could not log in.")
        return render_template("login.html")

这是login.html:

<form name="loginform" action="{{ url_for('login') }}" method="POST">
Username: <input type="text" name="username" size="30" /><br />
Password: <input type="password" name="password" size="30" /><br />
<input type="submit" value="Login" /><br />

现在,当用户访问/secret,他被重定向到/login?next=%2Fsecret。到目前为止,一切顺利 - “下一个”参数位于查询字符串中。

但是,当用户提交登录表单时,他会被重定向回索引页面,而不是返回到/secret URL.

我猜测原因是因为传入 URL 上可用的“next”参数未合并到登录表单中,因此在处理表单时不会作为变量传递。但是正确的方法是什么解决这个问题吗?

一种解决方案似乎可行 - 更改<form>标签来自

<form name="loginform" action="{{ url_for('login') }}" method="POST">

to:

<form name="loginform" method="POST">

删除“action”属性后,浏览器(至少 Windows 上的 Firefox 45)会自动使用当前 URL,从而使其继承?next=%2Fsecret查询字符串,成功将其发送到表单处理处理程序。

但是省略“action”表单属性并让浏览器将其填充到正确的解决方案中吗?它适用于所有浏览器和平台吗?

或者 Flask 或 Flask-login 是否打算以不同的方式处理这个问题?


如果您需要指定不同的action属性在您的表单中,您不能使用 Flask-Login 提供的下一个参数。无论如何,我建议将端点而不是 url 放入 url 参数中,因为这样更容易验证。这是我正在开发的应用程序中的一些代码,也许可以帮助您。

覆盖 Flask-Login 的未授权处理程序以使用端点而不是下一个参数中的 url:

@login_manager.unauthorized_handler
def handle_needs_login():
    flash("You have to be logged in to access this page.")
    return redirect(url_for('account.login', next=request.endpoint))

Use request.endpoint也可以在您自己的网址中:

{# login form #}
<form action="{{ url_for('account.login', next=request.endpoint) }}" method="post">
...
</form>

如果下一个参数存在且有效,则重定向到该端点,否则重定向到回退。

def redirect_dest(fallback):
    dest = request.args.get('next')
    try:
        dest_url = url_for(dest)
    except:
        return redirect(fallback)
    return redirect(dest_url)

@app.route("/login", methods=["GET", "POST"])
def login():
    ...
    if user_is_logged_in:
        flash("Logged in!")
        return redirect_dest(fallback=url_for('general.index'))
    else:
        flash("Sorry, but you could not log in.")
        return render_template("login.html")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Flask 和 Flask-login 传递“下一个”URL? 的相关文章

随机推荐