解决Flask Web request.args.get('next')问题
1、问题再现:目标实现的功能:当用户注册后,程序自动发送用于确认邮嘞窜虹律箱的连接到注册邮箱上,当用户点出确认链接后,转到登陆页面,用户输入登陆信息后达到自动确认邮箱的目的1. 创建登陆表单<form action="auth.login" method='POST'>...</form>2. 在User模型中添加生成token及验证token的方法from itsdangerous import TimedJSONWebSignatureSerializer as Serializerdef gernerate_token(self): s = Serializer(SECRET_KEY) token = s.dumps({'confirm':self.id}) return tokendef confirm_token(self, token): s = Serializer(SECRET_KEY) try: data = s.loads(token) if data.get('confirm') != self.id: return False else: self.confirmed=True db.session.add(self) db.session.commit() return True3.在登陆路由上的配置@auth.route('auth.login')def login(): form = loginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.email.data).first() if user is not None and user.verify_pass(form.password.data): login_user(user) return redirect(request.args.get('next') or url_for('main.index')) return redirect(url_for('main.index'))4. 在验证令牌路由上的配置@auth.route('/confirm/<token>')@login_requireddef confirm(token): if current_user.confirmed: flash('邮箱已经确认!') return redirect(url_for('main.index')) else: if user.confirm_token(token): flash('恭喜!邮箱确认成功!') else: flash('令牌错误或者过期!') return redirect('main.index')
2、按照以上步骤设置,令牌生成及发送功能已没有问题,唯独令牌验证上出现了问题。主要问题在于在登陆页面跳转时request.args.get('next')总是返回None, 这就使得用户登陆后无法实现邮箱确认的功能
3、解决方案:1. 问题是如何引起的:当用户提交表单后,表单中定义了处理表单数据的路由'auth.login',所以每次提交数据,都将跳转到auth/login这个连接去,而这链接中没有'next'这个参数,这就是为什么request.args.get('next') 总是返回None的原因。2. 解决问题的方案:修改登陆表单中的路由,去掉或者改为空action=''。这样修改后,邮箱验证的功能就正常了。