flask-用户认证(下)

本文介绍在Flask中实现用户确认账户的流程,包括使用itsdangerous生成安全的确认令牌,发送确认邮件,以及管理账户功能如修改密码和重设密码。详细阐述了确认账户的安全措施,如何生成和验证过期令牌,以及未确认账户的处理。同时,文章还涵盖了用户自主修改密码的步骤和重设密码的流程,确保账户的安全和管理。
摘要由CSDN通过智能技术生成

确认账户

对于某些特定类型的程序,有必要确认注册时用户提供的信息是否正确。常见要求是能通过提供的电 子邮件地址与用户取得联系。

为验证电子邮件地址, 用户注册后,程序会立即发送一封确认邮件。新账户先被标记成未激活状态,用户点击邮件中的链接后,才能激活。账户确认过程中,往往会要求用户点击一个包含确认令牌的特殊 URL 链接。

1. 使用itsdangerous生成确认令牌

确认邮件中最简单的确认链接是 http://www.example.com/auth/confirm/<id> 这种形式的URL,其 中 id 是数据库分配给用户的数字 id。用户点击链接后,处理这个路由的视图函数就将收到的用户id作为参数进行确认,然后将用户状态更新为已激活。

但是这种方式不是很安全,只要用户能判断确认链接的格式,就可以随便指定URL中的数字,从而确认任意账户。解决方法是把 URL 中的 id换成将相同信息安全加密后得到的令牌。

itsdangerous 提供了多种生成令牌的方法。其中, TimedJSONWebSignatureSerializer 类生成具有 过期时间的 JSON Web 签名(JSON Web Signatures, JWS)。这个类的构造函数接收的参数是一个密钥,在 Flask 程序中可使用 SECRET_KEY 设置。

dumps()方法为指定的数据生成一个加密签名,然后再对数据和签名进行序列化,生成令牌字符串。 expires_in 参数设置令牌的过期时间,单位为秒。 为了解码令牌, 序列化对象提供了 loads()方法,其唯一的参数是令牌字符串。这个方法会检验签 名和过期时间, 如果通过,返回原始数据。如果提供给 loads() 方法的令牌不正确或过期了,则抛 出异常。

我们可以将这种生成和检验令牌的功能可添加到 User 模型中。

【 app/models.py:确认用户账户】

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask import current_app

class User(UserMixin, db.Model):
    confirmed = db.Column(db.Boolean, default=False)
    def generate_confirmation_token(self, expiration=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({
  'confirm': self.id})
    def confirm(self, token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return False
        if data.get('confirm') != self.id:
            return False
        self.confirmed = True
        # 修改
        db.session.add(self)
        return True

generate_confirmation_token() 方法生成一个令牌,有效期默认为一小时。

confirm()方法检验令牌,如果检验通过,则把新添加的 confirmed 属性设为 True。

由于模型中新加入了一个列用来保存账户的确认状态,因此要生成并执行一个新的数据库迁移

2. 发送确认邮件

/register 路由把新用户添加到数据库中后,会重定向到 /index。在重定向之前,这个路由需要发 送确认邮件。

首先编辑邮件: 

【confirm.txt】

Dear {
   { user.username }},
Welcome to Flasky!
To confirm your account please click on the following link:
{
   { url_for('auth.confirm', token=token, _external=True) }}
Sincerely,
The Flasky Team
Note: replies to this email address are not monitored.

【confirm.html】

<p>Dear {
   { user.username }},</p>
<p>Welcome to <b>Flasky</b>!</p>
<p>To confirm your account please <a href="{
   { url_for('auth.confirm', 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.confirm', 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>

默认情况下, url_for() 生成相对 URL,例如 url_for('auth.confirm', token='abc') 返回的字符串是 '/auth/confirm/abc'。这不能够在电子邮件中发送的正确URL。

_external=True 参数要求程序生成完整的 URL,其中包含协议(http://或 https:// )、主机名和端口。

【app/auth/views.py:能发送确认邮件的注册路由】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值