接上章節:https://blog.csdn.net/Miao_Hen/article/details/105157765
講述:爲什麼generate_password_hash()函數針對同一密碼,生成不同的“密碼散列值”,而用戶登錄時可以判斷密碼是否正確
清晰的描述:A/B兩個用戶,都設置密碼爲“cat”,但是A/B兩個用戶生成的“password_hash”不一致;當A用戶登錄時,怎麼確定自己再次輸入“cat”,會匹配到正確的“password_hash”?
解答:因爲當用戶調用下方的方法時,並不是將“cat”重新進行加密爲新的“密碼散列值”,而是將數據庫保存的“password_hash”進行反向解碼,確認解碼結果是否和“cat"一致,是:返回True,不是:返回False
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
舉例:
# 模板
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)
password_hash = db.Column(db.String(128))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __init__(self, email=None, username=None, password=None):
self.email = email
self.username = username
self.password = password
@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 __repr__(self):
return f'<User {self.username}>'
if __name__ == '__main__':
u = User(email='[email protected]', username='ddd', password='cat')
u2 = User(email='[email protected]', username='ddd', password='cat')
print(u.password_hash)
print(u2.password_hash)
>>>pbkdf2:sha256:150000$WlU6hKVc$b85531b52dafbead09b983cd6942840ded3fd897bde528531c677cc95046c52e
>>>pbkdf2:sha256:150000$BXGUQbSK$7a8a1e95707688d4f46e4b586ff718e9ead8a3b55a3b60fe8a15cda8ec0cede4
可以看出相同的密碼兩次生成的密碼散列值不一致
此時我們將上述生成的兩個密碼散列值進行驗證,看是否解碼爲“cat”
# 修改上述的verify_password(self, password)函數:
def verify_password(self, password):
return check_password_hash('pbkdf2:sha256:150000$WlU6hKVc$b85531b52dafbead09b983cd6942840ded3fd897bde528531c677cc95046c52e', password)
def verify_password2(self, password):
return check_password_hash('pbkdf2:sha256:150000$BXGUQbSK$7a8a1e95707688d4f46e4b586ff718e9ead8a3b55a3b60fe8a15cda8ec0cede4', password)
# 將上次輸出的兩個密碼散列值當做匹配對象
if __name__ == '__main__':
print(verify_password('cat'))
print(verify_password2('cat'))
>>>True
>>>True
輸出結果全部爲True,由此可見,進行密碼驗證時,並非將‘輸入密碼’進行加密處理,而是將已經保存的密碼散列值進行反向解密,然後與輸入密碼進行匹配。