带相似度校验的哈希密码修改功能实现问题咨询
密码修改时新旧密码相似度校验的正确实现方法
你的代码核心问题是错误对比了哈希值的相似度,这完全行不通:
- 哈希算法(比如sha256)的特性是,明文哪怕只有一个字符差异,哈希结果都会天差地别。
- 哪怕新旧密码完全相同,werkzeug的
generate_password_hash会自动生成随机盐,每次生成的哈希值也不一样,所以SequenceMatcher对比哈希值根本无法判断明文相似度。
正确的实现步骤:
- 要求前端请求时同时传入旧密码明文和新密码明文。
- 先验证旧密码是否正确(用
check_password_hash对比存储的哈希和用户输入的旧密码)。 - 对比旧密码明文和新密码明文的相似度,而非哈希值。
修正后的代码:
from werkzeug.security import generate_password_hash, check_password_hash from difflib import SequenceMatcher @accounts.route('/<int:id>', methods=['PUT']) def update_password(id): try: account = db_session.query(Account).filter_by(id=id).first() if not account: return jsonify({'error': 'Account not found.'}), 404 json_data = request.get_json() try: # 注意:Schema需要添加old_password字段的校验规则 data = AccountPasswordSchema().load(json_data) except ValidationError as err: return jsonify({"error": err.messages}), 400 old_password_input = data.get('old_password') new_password = data.get('password') # 第一步:验证旧密码是否正确 if not check_password_hash(account.password_hash, old_password_input): return jsonify({'error': 'Old password is incorrect.'}), 400 # 第二步:对比明文密码的相似度 similarity_ratio = SequenceMatcher(None, old_password_input, new_password).ratio() if similarity_ratio > 0.8: return jsonify({'error': 'New password is too similar to the old password.'}), 400 # 更新密码(根据你的Account模型调整,若模型未自动处理哈希则手动生成) account.password = new_password # 若模型无自动哈希逻辑,替换为: # account.password_hash = generate_password_hash(new_password, method='sha256') db_session.commit() return jsonify({'message': 'Password successfully updated.'}), 200 except Exception as e: return jsonify({'error': str(e)}), 400
额外注意:
- 需在
AccountPasswordSchema中添加old_password字段的校验规则,确保前端能传入该参数。 - 先验证旧密码正确性是密码修改功能的基本安全要求,可防止未授权的密码篡改。
内容的提问来源于stack exchange,提问作者ussrback
相关产品推荐
相关产品推荐

