python - Flask中的用户确认问题

查看:103
本文介绍了python - Flask中的用户确认问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

在学习Flask-Web开发这本书的第八章遇到了问题,就是在数据库模型中添加确认用户账户的功能时,有这样一段代码:

class User(UserMixin,db.Model):

__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
email = db.Column(db.String(64),unique=True,index=True)
username=db.Column(db.String(64),unique=True,index=True)
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
password_hash = db.Column(db.String(128))
confirmed = db.Column(db.Boolean,default=False)

@property
def password(self):
    raise AttributeError('password is not a readable attribute.')

@password.setter
def password(self,password):
    self.password_hash =generate_password_hash(password)

def verify_password(self,password):
    return check_password_hash(self.password_hash,password)

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)
    db.session.commit()
    return True

def __repr__(self):
    return '<User %r>' % self.username

confirm()方法验证令牌。
其中,有一段是这样的:if data.get("confirm") != self.id,正常情况下data返回的不就是原数据么({'confirm':self.id}),加这段代码的意义是什么
书中有解释:confirm()方法还检查令牌中的id是否和存储在current_user中的已登录用户匹配。这里的current_user是否就是指正在进行验证的这个用户?对于Flask来说,尚未确认的用户也算已登录的用户吗,即current_user.is_authentiacated为True。将代码改为

          if data.get("confirm") != current_user.get_id():

可否?

以及最后一句话,添加这段代码:if data.get("confirm") != self.id,即使恶意用户知道如何生成签名令牌,也无法确认别人的账户。账户应该是指注册或者登录时的email吧,这段代码确认了confirm数据是否为用户唯一id号,和用户账户(email)有什么关系

解决方案

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)
    db.session.commit()
    return True
    

需要注意的是这里的tokenSECRET_KEY

这里的data经过了一次data=s.loads(token),如果token和SECRET_KEY不正确的话,get得到的id也是不正确的,这样就起到了验证的作用。

这里的账户指的是每个账户自己的id,就算恶意用户成功伪造了token,因为用户的id号不正确,这里无法成功验证。

登录和确认是两个属性,这两个之间没有耦合的关系,没有登录的账户也可以是确认过的,所以没有确认的账户也可以是登录状态的。

这篇关于python - Flask中的用户确认问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆