寫貼上自己寫的demo
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
password = db.Column(db.String(128))
rold_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __init__(self, username=None):
self.username = username
self.password_hash = ''
# 只讀明文密碼
@property
def password(self):
raise AttributeError('password is not a readable attribute')
# 計算密碼散列值並把得到的結果賦值給password_hash字段
# 寫入密碼,同時計算hash值,保存到模型中
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
# 接受一個參數(即密碼),將其傳給check_password_hash()函數,和存儲在User模型中的密碼散列值進行比對。
# 如果這個方法返回True,就表明密碼是正確的
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
def __repr__(self):
return f'<User {self.username}>'
如上圖所示: def password(self, password): 方法爲設置密碼
爲什麼每次設置生成的密碼散列值不一致呢,需要了解下 generate_password_hash(password)生成規則
def generate_password_hash(password, method="pbkdf2:sha256", salt_length=8):
salt = gen_salt(salt_length) if method != "plain" else ""
h, actual_method = _hash_internal(method, salt, password)
return "%s$%s$%s" % (actual_method, salt, h)
def gen_salt(length):
"""Generate a random string of SALT_CHARS with specified ``length``."""
if length <= 0:
raise ValueError("Salt length must be positive")
return "".join(_sys_rng.choice(SALT_CHARS) for _ in range_type(length))
上述第一個是generate_password_hash(password)方法;
第二個方法爲密碼“加鹽”操作 默認隨機生成一個“鹽值”
因此可以理解,相同的密碼設置,因爲加的“鹽”不一致,導致相同的密碼進行設計,生成不同的“密碼散列值”
還有一個疑問:那如何處理不同的用戶,使用相同的密碼登錄,可以驗證出用戶對應的“密碼散列值”一致呢
請關注下章節,實際應用中如何破解相同密碼設置,驗證用戶對應的“密碼散列值”