【发布时间】:2014-08-10 23:45:58
【问题描述】:
如何使用自定义装饰器限制对路由的访问?或者有没有更好更简单的方法?
以下是重置忘记密码的代码:
@auth.route('/reset', methods=['GET', 'POST'])
def password_reset_verify():
if not current_user.is_anonymous():
return redirect(url_for('main.index'))
form = PasswordResetVerifyForm()
if form.validate_on_submit():
return redirect(url_for('auth.password_reset', uid=form.uid.data))
return render_template('auth/reset.html', form=form)
在其他人验证上述路线之前,我不希望其他人访问此路线。因为你可以通过 /reset/123456789 更改其他人的密码
@auth.route('/reset/<uid>', methods=['GET', 'POST'])
def password_reset(uid):
if not current_user.is_anonymous():
return redirect(url_for('main.index'))
form = PasswordResetForm()
if form.validate_on_submit():
user = User.query.filter_by(uid=uid).first()
if user is None:
return redirect(url_for('main.index'))
if user.reset_password(form.password.data):
flash('Your password has been updated.')
return redirect(url_for('auth.login'))
else:
return redirect(url_for('main.index'))
return render_template('auth/reset.html', form=form)
如何编写我的自定义装饰器,以便客人无权进入 password_rest 路线。换句话说,password_rest 路由只是对该验证的一次访问。或者有没有办法可以将 password_rest 与 password_rest_verify 结合起来?
【问题讨论】:
-
你在这里使用什么烧瓶库?我知道
flask.ext.login有一个非常简单的装饰器。 -
你不应该在路由中包含
<uid>。我假设您知道用户已登录,因此可以从会话对象中检索他们的uid。在他们验证密码后,您设置一个额外的会话值password_reset_verified = True或类似值,然后在password_reset函数上检查它是否已设置,重置他们的密码,并从会话中清除该值。事实上,我看到您正在访问current_user,因此您可以从那里获取uid。 永远不要信任用户。 -
安全性很差,正如@sberry 所说,您永远不会真正使用 uid 来重置密码...分配唯一令牌,发送电子邮件并要求用户通过电子邮件确认(当然,这意味着在注册过程中也会验证电子邮件)。
-
@sberry 不,登录用户永远无法访问密码休息页面,还有另一种方法可以更改登录用户的密码。我从以前的 PasswordResetVerifyForm 中检索他们的 uid,并将 uid 值传递给 password_reset(uid) 以供用户查询。
-
@petkostas 是的,我确实意识到这是很差的安全性。我没有设置烧瓶电子邮件,我希望用户能够在网站上重置他们的密码,而不是通过电子邮件发送并单击链接。也许我会生成一个唯一的令牌来替换
标签: python web-applications flask