You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

IoT系统RPC登录场景:如何在Django哈希器前实现自定义哈希函数?

没问题,这个需求其实可以通过定制Django的密码哈希器来完美解决,不用去硬改make_password的源码——毕竟Django本身就提供了扩展密码处理流程的机制,咱们一步步来:

实现方式:自定义密码哈希器

Django的密码系统是基于**哈希器(Password Hasher)**工作的,我们可以继承它内置的哈希器(比如默认的PBKDF2PasswordHasher),重写核心方法,让它在执行常规哈希前先调用你的hash_used_by_RPC函数。

1. 编写自定义哈希器代码

在你的Django项目里找一个合适的app(比如专门处理用户逻辑的accounts),创建一个hashers.py文件,然后写入以下代码:

from django.contrib.auth.hashers import PBKDF2PasswordHasher

# 替换成你实际的RPC哈希实现
def hash_used_by_RPC(password):
    # 举个例子,假设RPC用的是SHA256哈希(实际建议用符合安全标准的算法)
    import hashlib
    return hashlib.sha256(password.encode('utf-8')).hexdigest()

class RPCPreHashPasswordHasher(PBKDF2PasswordHasher):
    # 自定义算法标识,必须唯一
    algorithm = "rpc_pre_hash_pbkdf2"

    def encode(self, password, salt, iterations=None):
        # 第一步:先对明文密码执行RPC哈希
        rpc_hashed_pwd = hash_used_by_RPC(password)
        # 第二步:把RPC哈希后的结果传给父类,执行Django常规的PBKDF2哈希
        return super().encode(rpc_hashed_pwd, salt, iterations)

    def verify(self, password, encoded):
        # 验证时也要先做RPC哈希,再用父类的验证逻辑
        rpc_hashed_pwd = hash_used_by_RPC(password)
        return super().verify(rpc_hashed_pwd, encoded)

2. 配置Django使用自定义哈希器

打开项目根目录的settings.py,找到PASSWORD_HASHERS配置项(如果没有就新增),把我们的自定义哈希器放在最前面,确保Django优先使用它:

PASSWORD_HASHERS = [
    # 替换成你的哈希器实际路径,比如accounts.hashers.RPCPreHashPasswordHasher
    'your_app_name.hashers.RPCPreHashPasswordHasher',
    # 保留Django默认的哈希器,用于兼容旧密码(如果有的话)
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.Argon2PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]

3. 为什么不直接修改make_password?

Django的make_password函数底层是调用配置的哈希器的encode方法来生成密码哈希的,通过定制哈希器的方式:

  • 完全符合Django的扩展规范,不用修改框架源码,更易维护
  • 自动兼容Django的密码验证、密码升级等原生功能
  • 你的两个密码验证函数都能直接正常工作:
    • djangos_pass_check:直接调用user.check_password(clearPassNoHash)即可,因为自定义哈希器的verify方法会自动先执行RPC哈希
    • RPC_pass_check:传入的RpcHashPassword已经是RPC哈希后的结果,user.check_password会直接用父类的逻辑验证它和数据库中存储的哈希是否匹配

验证效果

当你在Django后台创建用户、或者用户注册设置密码时,Django会自动先对明文密码执行hash_used_by_RPC,再进行常规的PBKDF2哈希,最终把两次哈希后的结果存储到数据库。而验证时不管是传入明文密码还是RPC哈希后的密码,都能正确匹配。

内容的提问来源于stack exchange,提问作者BushLee

火山引擎 最新活动