Dav*_*ite 15 python forms flask flask-login
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")
Run Code Online (Sandbox Code Playgroud)
这是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 />
Run Code Online (Sandbox Code Playgroud)
现在,当用户访问时/secret,他被重定向到/login?next=%2Fsecret.到目前为止,非常好 - 查询字符串中的"next"参数.
但是,当用户提交登录表单时,他将被重定向回索引页面,而不是返回到/secretURL.
我猜测原因是因为传入URL上的"next"参数没有合并到登录表单中,因此在处理表单时不会作为变量传递.但是正确的方法是什么解决这个?
一个解决方案似乎有效 - <form>从中更改标签
<form name="loginform" action="{{ url_for('login') }}" method="POST">
Run Code Online (Sandbox Code Playgroud)
至:
<form name="loginform" method="POST">
Run Code Online (Sandbox Code Playgroud)
删除"action"属性后,浏览器(至少是Windows上的Firefox 45)会自动使用当前URL,从而继承?next=%2Fsecret查询字符串,该字符串会成功将其发送到表单处理处理程序.
但是省略了"action"表单属性并让浏览器在正确的解决方案中填充它?它适用于所有浏览器和平台吗?
或者Flask或Flask-login是否打算以不同的方式处理?
tim*_*kro 20
如果需要在表单中指定其他操作属性,则无法使用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))
Run Code Online (Sandbox Code Playgroud)
也可以request.endpoint在您自己的网址中使用:
{# login form #}
<form action="{{ url_for('account.login', next=request.endpoint) }}" method="post">
...
</form>
Run Code Online (Sandbox Code Playgroud)
如果存在并且有效,则在下一个参数中重定向到端点,否则重定向到回退.
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")
Run Code Online (Sandbox Code Playgroud)