Flask-login 的文档讨论了如何处理“下一个”URL。这个想法似乎是:
- 用户转到
/secret
- 用户被重定向到登录页面(例如
/login
) - 登录成功后,用户被重定向回
/secret
我发现的唯一使用 Flask-login 的半完整示例是 https://gist.github.com/bkdinoop/6698956 。它很有用,但由于它不包含 HTML 模板文件,我想看看是否可以重新创建它们作为自我训练练习。
这是 /secret
和 /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 上可用的“下一个”参数没有合并到登录表单中,因此在处理表单时没有作为变量传递。但是正确的方法是什么解决这个?
一种解决方案似乎有效 - 更改 <form>
标签
<form name="loginform" action="{{ url_for('login') }}" method="POST">
到:
<form name="loginform" method="POST">
删除“action”属性后,浏览器(至少是 Windows 上的 Firefox 45)自动使用当前 URL,使其继承 ?next=%2Fsecret
查询字符串,成功将其发送到表单处理程序。
但是省略“action”表单属性并让浏览器填写正确的解决方案吗?它适用于所有浏览器和平台吗?
或者 Flask 或 Flask-login 是否打算以不同的方式处理这个问题?
原文由 David White 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果您需要在表单中指定不同的 操作 属性,则不能使用 Flask-Login 提供的下一个参数。无论如何,我建议将端点而不是 url 放入 url 参数中,因为它更容易验证。这是我正在处理的应用程序的一些代码,也许这可以帮助你。
覆盖 Flask-Login 的未授权处理程序以在下一个参数中使用端点而不是 url:
在您自己的网址中也使用
request.endpoint
:如果存在且有效,则重定向到下一个参数中的端点,否则重定向到回退。