在用flask实现一个密码重置功能时,遇到如下问题:
report:
Method Not Allowed The method is not allowed for the requested URL.
1)登录界面放置重置密码超链接,指向/auth/start_resetpwd
2)/auth/start_resetpwd渲染start_resetpwd.html界面(提示用户输入注册邮箱,和"下一步"按钮),用户输入注册邮箱,点击"下一步"按钮后,系统向用户的注册邮箱发送一个连接(形如/auth/resetpwd/),提示用户查看邮箱,使用邮件中的连接进入下一步
3)/auth/resetpwd/响应:检查token是否有效,如果有效,则渲染“/auth/resetpwd.html”。“/auth/resetpwd/html”界面,要求用户输入两遍新密码,然后点击“确认”按钮。当点击“确认”按钮后,便弹出如下信息:
report:
Method Not Allowed The method is not allowed for the requested URL.
@auth.route('/resetpwd/' )
def resetpassword_checktoken(token):
email = session.get('email')
if email:
user = User.query.filter_by(email=email).first()
if user and user.check_resetpwd_token(token):
form = ResetpasswordForm()
return render_template('auth/resetpwd.html', form=form)//pos A
flash('Email %s has not been registered or the token has been expired!' % (email))
return redirect(url_for('auth.login'))
@auth.route('/resetpwd', methods=['GET', 'POST'])
def resetpwd():
form = ResetpasswordForm()
email = session.get('email')
user = User.query.filter_by(email=email).first()
logger.info('resetpwd user %s' % user.username)//pos B
if user and form.validate_on_submit():
user.password = form.password.data
db.session.add(user)
logger.info('resetpwd user2 %s' % user.username)//pos C
db.session.commit()
logger.info('resetpwd user3 %s' % user.username)
logger.flush()
return redirect(url_for('auth.login'))
logger.info('resetpwd user4 %s' % user.username)
return render_template('auth/resetpwd.html', form=form)
log信息如下:
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:30] "GET /auth/resetpassword HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:36] "POST /auth/resetpassword HTTP/1.1" 302 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:36] "GET /auth/login HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:49] "GET /auth/resetpwd/eyJhbGciOiJIUzUxMiIsImlhdCI6MTU2NTgzMTE5NiwiZXhwIjoxNTY1ODMxNzk2fQ.eyJyZXNldHB3ZCI6MX0.xd9hzjI7lbfE16WkeeMMKUiz7nS6GHT7wos-W9lFnl3V7mReDDjf3wX_eR4giZzs_YJj03v7AvOaVMF8G-SKgQ HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:07:43] "POST /auth/resetpwd/eyJhbGciOiJIUzUxMiIsImlhdCI6MTU2NTgzMTE5NiwiZXhwIjoxNTY1ODMxNzk2fQ.eyJyZXNldHB3ZCI6MX0.xd9hzjI7lbfE16WkeeMMKUiz7nS6GHT7wos-W9lFnl3V7mReDDjf3wX_eR4giZzs_YJj03v7AvOaVMF8G-SKgQ HTTP/1.1" 405 -
有如下问题:
1)当运行万pos A后,期望打印pos B,但是B没有打印
2)点击“确认”后,期望打印pos C,但是C没有打印
3)根据werkzeug的log信息可以看到 /auth/resetpwd/的GET响应后,调用/auth/resetpwd/的POST的处理。期望是:/auth/resetpwd/的GET -> /auth/resetpwd GET -> /auth/resetpwd POST
所以问题出在token检查无误后,应用重定向到/auth/resetpwd下。
代码如下:
@auth.route('/resetpwd/' )
def resetpassword_checktoken(token):
email = session.get('email')
if email:
user = User.query.filter_by(email=email).first()
if user and user.check_resetpwd_token(token):
redirect(url_for('auth.resetpwd'))
flash('Email %s has not been registered or the token has been expired!' % (email))
return redirect(url_for('auth.login'))
对于出现
Method Not AllowedThe method is not allowed for the requested URL.
一般是因为URL响应不支持一定的操作,比如POST。所以处理方法是
@auth.route('/resetpwd/' , methods=['GET', 'POST'])
def resetpassword_checktoken(token):
但这次的问题是,URL响应划分不合理,启用新界面后,良好的做法是为新界面启用一个新的URL(当然,方法不唯一。选择自己喜欢的方式就行)。