Flask Admin:创建新用户时如何自动生成密码哈希?
嘿,这个问题我太熟了!结合Django的用户模型和Admin视图,用bcrypt自动生成密码哈希其实很 straightforward,我给你分场景讲清楚:
第一步:让Django支持bcrypt哈希算法
首先Django本身就支持bcrypt作为密码哈希器,但需要先安装依赖库,然后在配置里指定优先级:
- 安装bcrypt依赖:
pip install bcrypt
- 修改
settings.py配置,把bcrypt的哈希器放在最前面(这样Django会优先用它来哈希新密码):
PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', # 优先用bcrypt 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.ScryptPasswordHasher', ]
第二步:在Admin中实现自动哈希的几种方式
如果你用的是默认的User模型或者自定义用户模型,下面两种方法都适用:
方式1:重写UserAdmin的save_model方法
这种方式直接在Admin层控制密码哈希逻辑,适合需要自定义Admin行为的场景:
# admin.py from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.hashers import make_password from .models import CustomUser # 如果你用自定义用户模型,否则导入默认User class CustomUserAdmin(UserAdmin): def save_model(self, request, obj, form, change): # 仅在创建新用户(不是编辑)且密码是明文时处理 if not change and obj.password and not obj.password.startswith('bcrypt$'): # 指定用bcrypt哈希器生成密码哈希 obj.password = make_password(obj.password, hasher='bcrypt_sha256') super().save_model(request, obj, form, change) # 注册你的用户模型和自定义Admin admin.site.register(CustomUser, CustomUserAdmin)
方式2:利用Django信号自动处理
信号是全局钩子,不管是通过Admin、代码还是其他方式创建用户,都会自动触发哈希逻辑,更通用:
- 创建
signals.py文件:
# signals.py from django.db.models.signals import pre_save from django.dispatch import receiver from django.contrib.auth.hashers import make_password from .models import CustomUser @receiver(pre_save, sender=CustomUser) def hash_user_password(sender, instance, **kwargs): # 检查密码是否未被哈希(避免重复哈希已加密的密码) if instance.password and not instance.password.startswith(('bcrypt$', 'pbkdf2$', 'argon2$')): instance.password = make_password(instance.password, hasher='bcrypt_sha256')
- 在
apps.py中注册信号,确保Django启动时加载:
# apps.py from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): import your_app_name.signals # 替换成你的app名称
额外提示:代码创建用户的情况
如果你通过代码调用create_user方法创建用户(比如CustomUser.objects.create_user(username='test', password='plain_pass')),Django的内置方法会自动调用set_password,而set_password会优先使用你配置的bcrypt哈希器,所以不需要额外写逻辑,直接用就行!
内容的提问来源于stack exchange,提问作者spitfiredd
相关产品推荐
相关产品推荐

