You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于与Django内置User一对一模型的password_crypt字段实现认证

嘿,这个需求我之前帮朋友处理过类似的,结合你用的Python2.7和Django1.10版本,咱们完全可以通过自定义认证后端来实现——既能用你自定义模型里的pbkdf2_sha512密码字段做认证,又能完整保留Django内置User的所有功能(比如Token、权限这些)。下面一步步来操作:

1. 编写自定义认证后端

Django的认证系统支持自定义后端,我们只需要实现authenticate()和get_user()两个核心方法就行。在你的app目录下新建一个backends.py文件,写入以下代码:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from yourapp.models import YourCustomUserModel  # 替换成你的自定义模型名
import hashlib
import base64
from django.utils.crypto import constant_time_compare

class CustomPasswordBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            # 先通过用户名找到内置User对象
            user = User.objects.get(username=username)
            # 找到关联的自定义模型实例(替换成你一对一字段的related_name)
            custom_user = user.your_custom_user_related_name
            # 解析password_crypt字段:pbkdf2_sha512的格式一般是「算法$迭代次数$盐$哈希值」
            algorithm, iterations, salt, hash_val = custom_user.password_crypt.split('$', 3)
            
            # 确保是我们需要的pbkdf2_sha512算法
            if algorithm != 'pbkdf2_sha512':
                return None
            
            # 用相同参数计算输入密码的哈希值
            iterations = int(iterations)
            derived_key = hashlib.pbkdf2_hmac(
                'sha512', 
                password.encode('utf-8'), 
                salt.encode('utf-8'), 
                iterations
            )
            derived_key_b64 = base64.b64encode(derived_key).decode('utf-8')
            
            # 用constant_time_compare防止计时攻击,确保密码验证安全
            if constant_time_compare(derived_key_b64, hash_val):
                return user  # 返回内置User对象,这样所有内置功能都能正常使用
        except (User.DoesNotExist, YourCustomUserModel.DoesNotExist):
            # 找不到用户或关联模型时返回None
            return None
        return None

    def get_user(self, user_id):
        # 根据用户ID获取内置User对象,这是认证后端必须实现的方法
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

⚠️ 注意:记得替换代码里的YourCustomUserModel为你实际的自定义模型名,还有your_custom_user_related_name要和你一对一关联字段的related_name一致——如果没设置related_name,默认是小写的模型名(比如你的模型叫UserProfile,默认就是userprofile)。

2. 配置Django使用自定义后端

打开项目的settings.py,找到AUTHENTICATION_BACKENDS配置项(如果没有就新建),添加咱们的自定义后端:

AUTHENTICATION_BACKENDS = [
    'yourapp.backends.CustomPasswordBackend',  # 优先使用自定义后端
    'django.contrib.auth.backends.ModelBackend',  # 保留默认后端,以备不时之需
]

这样Django会依次尝试这些后端进行认证,既支持你的自定义密码字段,也能兼容内置User的密码验证(如果需要的话)。

3. 密码生成工具函数(可选)

如果需要给用户创建/更新密码,得生成符合pbkdf2_sha512格式的哈希值存入password_crypt字段。可以写一个工具函数:

import hashlib
import base64
import os

def generate_pbkdf2_sha512(password):
    algorithm = 'pbkdf2_sha512'
    iterations = 100000  # 迭代次数可根据安全需求调整
    salt = base64.b64encode(os.urandom(16)).decode('utf-8')  # 生成随机盐
    derived_key = hashlib.pbkdf2_hmac(
        'sha512', 
        password.encode('utf-8'), 
        salt.encode('utf-8'), 
        iterations
    )
    derived_key_b64 = base64.b64encode(derived_key).decode('utf-8')
    return f"{algorithm}${iterations}${salt}${derived_key_b64}"

使用示例:

from yourapp.models import YourCustomUserModel
from yourapp.utils import generate_pbkdf2_sha512  # 假设函数存在utils.py里

# 假设已经有一个关联的User对象
custom_user = YourCustomUserModel.objects.get(user=existing_user)
custom_user.password_crypt = generate_pbkdf2_sha512("user_new_password")
custom_user.save()
4. 保留内置User功能的注意事项
  • 因为咱们在认证成功后返回的是内置User对象,所以Token认证、权限系统、Admin后台这些功能都能正常使用,完全不受影响。
  • 如果你不需要内置User的password字段,可以把它设为无效值(比如!),防止有人通过默认后端登录,但要确保这个值无法被认证。
  • 一对一关联字段建议设置on_delete=models.CASCADE,确保User对象删除时,自定义模型也会被同步删除。
5. 测试验证

可以在Django Shell里快速测试认证逻辑:

from django.contrib.auth import authenticate

# 测试正确密码
user = authenticate(username="test_user", password="correct_password")
if user:
    print("认证成功!")
    # 测试Token生成(如果用DRF的话)
    from rest_framework.authtoken.models import Token
    token, created = Token.objects.get_or_create(user=user)
    print("生成的Token:", token.key)
else:
    print("认证失败!")

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:14:26