第八章 用户身份验证(管理账户三)

修改电子邮件地址:用户可以修改注册电子邮件的地址,不过接受新地址之前,必须使用确认邮件进行验证。为了验证新地址,应用发送一封包含令牌的邮件。服务器收到令牌后,再更新用户对象。服务器收到令牌之前,可以把新电子邮件地址保存在数据库一个新字段中,或者将其与id一起保存在令牌中

1)点击修改电子邮件,进入“Change Your Email Address”界面:

    

2)提交1)中的表单发送一封电子邮件,并重定向到主界面:

     

templates/auth/change_email.html:修改电子邮件模板

{% extends 'base.html' %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Flasky - Change Email Address{% endblock %}

{% block page_content %}
    <div class="page-header"><h1>Change Your Email Address</h1></div>
    <div class="col-md-4">{{ wtf.quick_form(form) }}</div>
{% endblock %}

templates/auth/email/change_email.html:包含邮件修改令牌的邮件

<p>Dear {{ user.username }},</p>
<p>To confirm your new email address <a href="{{ url_for('auth.change_email', token=token, _external=True) }}">
click here</a>.</p>
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
<p>{{ url_for('auth.change_email', token=token, _external=True) }}</p>
<p>Sincerely,</p>
<p>The Flasky Team</p>
<p><small>Note: replies to this email address are not monitored.</small></p>

 auth/forms.py:修改邮箱表单

class ChangeEmailForm(FlaskForm):
    email = StringField('New Email', validators=[DataRequired(), Length(1, 64), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Update Email Address')

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first():
            raise ValidationError('Email already registered.')

3)处理1)中表单的视图函数

auth/views.py:处理ChangeEmailForm表单的视图函数

@auth.route('/change_email', methods=['GET', 'POST'])
@login_required
def change_email_request():
    form = ChangeEmailForm()
    if form.validate_on_submit():
        if current_user.verify_password(form.password.data):
            new_email = form.email.data
            token = current_user.generate_email_change_token(new_email)
            send_email(new_email, 'Confirm your email address', 'auth/email/change_email', user=current_user,
                       token=token)
            flash('An email with instructions to confirm your new email '
                  'address has been sent to you.')
            return redirect(url_for('main.index'))
        else:
            flash('Invalid email or password.')
    return render_template('auth/change_email.html', form=form)

app/models.py:User模型中添加修改邮箱需要的令牌以及修改邮箱的方法:

    def generate_email_change_token(self, new_email, expiration=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'change_email': self.id, 'new_email': new_email}).decode('utf-8')

    def change_email(self, token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token.encode('utf-8'))
        except:
            return False
        if data.get('change_email') != self.id:
            return False
        new_email = data.get('new_email')
        if new_email is None:
            return False
        if self.query.filter_by(email=new_email).first() is not None:
            return False
        self.email = new_email
        db.session.add(self)
        return True

注:在产生加密令牌时,将用户输入的新邮件地址也保存在了令牌中,在修改电子邮件地址时,再从令牌中获取。

4)点击收到的包含邮箱修改令牌的电子邮件链接

       

5)处理4)中链接的视图处理函数

auth/views.py:

@auth.route('/change_email/<token>', methods=['GET', 'POST'])
@login_required
def change_email(token):
    if current_user.change_email(token):
        db.session.commit()
        flash('Your email address has been updated.')
    else:
        flash('Invalid request.')
    return redirect(url_for('main.index'))

注:由于User模型中已经封装了change_email方法,所以此处直接传入令牌,调用即可。

在4)中的主页中输入新的电子邮件地址登录,登录成功后将重定向到首页

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值