在学习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)有什么关系?
What needs to be noted is the
token
和SECRET_KEY
here.The data here has been passed once
data=s.loads(token)
,如果token和SECRET_KEY不正确的话,get
The ID obtained is also incorrect, which plays a role in verification.The account here refers to each account's own ID. Even if a malicious user successfully forges the token, the user's ID number is incorrect and cannot be successfully verified here.
Login and confirmation are two attributes. There is no coupling relationship between the two. An unlogged account can also be confirmed, so an unconfirmed account can also be logged in.