我在我的应用程序中使用Flask-login的@login_required
装饰器来处理某些路径。在未登录的情况下导航到这些路线时,我被重定向到登录页面。到目前为止一切都很好。
重定向的网址如下所示:/login?next=%2Fusers
看起来它对下一个参数进行了url编码,这是我在我遇到过的示例中没有看到的。登录重定向到next
后总是失败并回到索引页面。我认为这是因为next
是url编码的。
我应该采取不同的方式吗?我刚刚开始深入研究Flask框架并使用示例进行操作,因此我不太了解最佳处理方法。
以下是一个示例路线:
login_manager.login_view = 'login'
@app.route('users')
@login_required
def users():
return 'Test'
我的登录路线如下:
@app.route('/login')
def login():
error = None
next = request.args.get('next')
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if authenticate_user(username, password):
user = User.query.filter_by(username=username).first()
if login_user(user):
flash("You have logged in")
session['logged_in'] = True
return redirect(next or url_for('index', error=error))
error = "Login failed"
return render_template('login.html', login=True, next=next, error=error)
提前感谢您的帮助。
答案 0 :(得分:3)
我想通了,导航到受登录保护的路由(在此示例中为/ requests)将导致重定向到具有next
参数的登录页面。
/login?next=%2Frequests
在我的登录模板中,我有这个:
<form action="{{ url_for('login') }}" method='POST'>
这导致表单在没有任何参数的情况下发布到/login
路由。删除action
属性或将其更改为action=""
会导致将表单发布到其自己的URL,其中包含原始查询字符串。另一种选择是在url_for中包含next=next
。
<form action="{{ url_for('login', next=next) }}" method='POST'>
答案 1 :(得分:0)
你走了:
import urllib
@app.route('/login')
def login():
error = None
next = urllib.unquote_plus(request.args.get('next'))
...
答案 2 :(得分:0)
如果有人像我一样发现这个问题,那么这个实现对我有用。问题是登录的POST表单只进入/ login,导致下一个URL被丢弃。根据Kevan的建议,如果您将next=request.args.get('next'))
添加到登录表单的操作中,它将传递下一个参数。
在我的登录功能中
@app.route('/login', methods = ['GET', 'POST'])
def login():
next = request.args.get('next')
if request.method == 'POST':
...Confirm User...
if next:
return redirect(next)
else:
return redirect('/')
在我的登录表单中
<form method="post" action="{{ url_for('login', next=request.args.get('next')) }}" enctype="multipart/form-data">
答案 3 :(得分:0)
出于安全考虑,应考虑对下一个参数进行检查,如
中所建议https://flask-login.readthedocs.io/en/latest/#login-example
@app.route('/login', methods=['GET', 'POST'])
def login():
# Here we use a class of some kind to represent and validate our
# client-side form data. For example, WTForms is a library that will
# handle this for us, and we use a custom LoginForm to validate.
form = LoginForm()
if form.validate_on_submit():
# Login and validate the user.
# user should be an instance of your `User` class
login_user(user)
flask.flash('Logged in successfully.')
next = flask.request.args.get('next')
# is_safe_url should check if the url is safe for redirects.
# See http://flask.pocoo.org/snippets/62/ for an example.
if not is_safe_url(next):
return flask.abort(400)
return flask.redirect(next or flask.url_for('index'))
return flask.render_template('login.html', form=form)