尝试使用 Flask-Security 手动确认用户电子邮件时确认令牌无效
Invalid Confirmation Token when trying to confirm user email manually with Flask-Security
试图弄清楚我调用 send_confirmation_instructions 和使用内置的重新发送确认指令表单调用它时有什么不同。
这是我的新用户视图中的调用:
newuser = User(
email = newform.email.data,
first_name = newform.first_name.data,
last_name = newform.last_name.data,
business_name = newform.business_name.data,
roles = [Role.query.filter_by(id=role_id).first() for role_id in newform.roles.data],
active = True
)
if newform.req_conf.data:
send_confirmation_instructions(newuser)
else:
newuser.confirmed_at = datetime.utcnow()
这是来自发送确认视图的内置调用:
def send_confirmation():
"""View function which sends confirmation instructions."""
form_class = _security.send_confirmation_form
if request.json:
form = form_class(MultiDict(request.json))
else:
form = form_class()
if form.validate_on_submit():
send_confirmation_instructions(form.user)
if request.json is None:
do_flash(*get_message('CONFIRMATION_REQUEST', email=form.user.email))
if request.json:
return _render_json(form)
return _security.render_template(config_value('SEND_CONFIRMATION_TEMPLATE'),
send_confirmation_form=form,
**_ctx('send_confirmation'))
据我所知,所有的魔法都发生在这个函数上:
send_confirmation_instructions(用户)
我能说出我如何调用它和 Flask-Security 如何调用它的唯一区别是我使用的是用户实例,而内置函数使用 form.user.
追踪它使用的形式,我什至看不到 form.user 的分配位置:
class SendConfirmationForm(Form, UserEmailFormMixin):
submit = SubmitField(get_form_field_label('send_confirmation'))
def __init__(self, *args, **kwargs):
super(SendConfirmationForm, self).__init__(*args, **kwargs)
if request.method == 'GET':
self.email.data = request.args.get('email', None)
def validate(self):
if not super(SendConfirmationForm, self).validate():
return False
if self.user.confirmed_at is not None:
self.email.errors.append(get_message('ALREADY_CONFIRMED')[0])
return False
return True
我现在很迷茫,所以我向你们寻求帮助。知道我做错了什么吗?
决定尝试提交到数据库,然后发送确认,果然有效。不确定为什么会有所不同,因为据我所知,none 函数使用或更改数据库中的任何内容,但显然我遗漏了一些东西。
修改代码如下,现在一切正常!
if newform.req_conf.data:
db.session.add(newuser)
db.session.commit()
send_confirmation_instructions(newuser)
else:
newuser.confirmed_at = datetime.utcnow()
db.session.add(newuser)
db.session.commit()
试图弄清楚我调用 send_confirmation_instructions 和使用内置的重新发送确认指令表单调用它时有什么不同。
这是我的新用户视图中的调用:
newuser = User(
email = newform.email.data,
first_name = newform.first_name.data,
last_name = newform.last_name.data,
business_name = newform.business_name.data,
roles = [Role.query.filter_by(id=role_id).first() for role_id in newform.roles.data],
active = True
)
if newform.req_conf.data:
send_confirmation_instructions(newuser)
else:
newuser.confirmed_at = datetime.utcnow()
这是来自发送确认视图的内置调用:
def send_confirmation():
"""View function which sends confirmation instructions."""
form_class = _security.send_confirmation_form
if request.json:
form = form_class(MultiDict(request.json))
else:
form = form_class()
if form.validate_on_submit():
send_confirmation_instructions(form.user)
if request.json is None:
do_flash(*get_message('CONFIRMATION_REQUEST', email=form.user.email))
if request.json:
return _render_json(form)
return _security.render_template(config_value('SEND_CONFIRMATION_TEMPLATE'),
send_confirmation_form=form,
**_ctx('send_confirmation'))
据我所知,所有的魔法都发生在这个函数上: send_confirmation_instructions(用户)
我能说出我如何调用它和 Flask-Security 如何调用它的唯一区别是我使用的是用户实例,而内置函数使用 form.user.
追踪它使用的形式,我什至看不到 form.user 的分配位置:
class SendConfirmationForm(Form, UserEmailFormMixin):
submit = SubmitField(get_form_field_label('send_confirmation'))
def __init__(self, *args, **kwargs):
super(SendConfirmationForm, self).__init__(*args, **kwargs)
if request.method == 'GET':
self.email.data = request.args.get('email', None)
def validate(self):
if not super(SendConfirmationForm, self).validate():
return False
if self.user.confirmed_at is not None:
self.email.errors.append(get_message('ALREADY_CONFIRMED')[0])
return False
return True
我现在很迷茫,所以我向你们寻求帮助。知道我做错了什么吗?
决定尝试提交到数据库,然后发送确认,果然有效。不确定为什么会有所不同,因为据我所知,none 函数使用或更改数据库中的任何内容,但显然我遗漏了一些东西。
修改代码如下,现在一切正常!
if newform.req_conf.data:
db.session.add(newuser)
db.session.commit()
send_confirmation_instructions(newuser)
else:
newuser.confirmed_at = datetime.utcnow()
db.session.add(newuser)
db.session.commit()