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

如何在使用自定义认证的Django项目中实现密码哈希?

Django自定义认证下实现密码哈希的步骤

1. 修改用户模型(models.py)

首先调整密码字段长度——Django生成的哈希密码约128位,原max_length=100不够用,需改为255;然后新增密码哈希与验证方法,确保密码存入数据库前完成哈希,同时提供统一的密码验证逻辑。

修改后的代码:

from django.db import models
from django.contrib.auth.hashers import make_password, check_password

class UserTable(models.Model):
    sl_num = models.CharField(max_length=100)
    name = models.CharField(max_length=100)
    phone_no = models.CharField(max_length=100)
    email = models.EmailField(blank=False, null=False)
    location = models.CharField(max_length=100)
    department = models.CharField(max_length=100)
    status = models.CharField(max_length=100)
    role=models.CharField(max_length=100)
    username=models.CharField(max_length=100, unique=True)  # 建议添加unique确保用户名唯一
    password=models.CharField(max_length=255)  # 加长长度适配哈希值

    def __str__(self):
        return self.name

    def set_password(self, raw_password):
        # 专门用于设置密码的方法,自动哈希处理
        self.password = make_password(raw_password)
        self.save()

    def check_password(self, raw_password):
        # 验证明文密码与哈希密码是否匹配
        return check_password(raw_password, self.password)

2. 处理用户创建/密码修改逻辑

无论通过表单还是脚本创建/修改用户,都不能直接将明文密码赋值给password字段,必须调用新增的set_password()方法完成哈希:

示例创建用户逻辑:

def create_user(request):
    if request.method == 'POST':
        raw_password = request.POST.get('password')
        # 初始化用户对象,不直接赋值password
        user = UserTable(
            sl_num=request.POST.get('sl_num'),
            name=request.POST.get('name'),
            phone_no=request.POST.get('phone_no'),
            email=request.POST.get('email'),
            location=request.POST.get('location'),
            department=request.POST.get('department'),
            status=request.POST.get('status'),
            role=request.POST.get('role'),
            username=request.POST.get('username')
        )
        user.set_password(raw_password)  # 调用方法哈希密码并保存
        user.save()
        # 后续跳转或提示逻辑

3. 修改登录验证逻辑(views.py)

原登录逻辑直接用明文密码查询数据库,现在改为先通过用户名找到用户,再调用check_password()验证密码是否匹配:

修改后的代码:

def asset_login(request):
    if request.method == 'POST':
        username = request.POST.get('user_id')
        raw_password = request.POST.get('password')
        try:
            # 仅通过用户名查询用户,不包含密码条件
            user = UserTable.objects.get(username=username)
            # 验证密码是否匹配
            if user.check_password(raw_password):
                if user.status == 'inactive':
                    messages.error(request, 'Your account is inactive.')
                    return redirect('asset_login')
                request.session['name'] = user.name
                request.session['role'] = user.role
                # 角色跳转逻辑保持不变
                if user.role == 'admin':
                    return redirect('admin_dashboard')
                elif user.role == 'ciso':
                    return redirect('ciso_dashboard')
                elif user.role == 'fnhead':
                    return redirect('fnhead_dashboard')
                elif user.role == 'systemadmin':
                    return redirect('systemadmin_dashboard')
                elif user.role == 'assetowner':
                    return redirect('assetowner_dashboard')
                else:
                    messages.error(request, 'Unknown user position')
                    return redirect('asset_login')
            else:
                # 密码不匹配提示
                messages.error(request, 'Invalid username or password')
                return redirect('asset_login')
        except UserTable.DoesNotExist:
            messages.error(request, 'Invalid username or password')
            return redirect('asset_login')
    return render(request, 'asset.html')

额外处理:历史明文密码批量哈希

如果数据库中已有明文密码,可通过Django Shell批量更新为哈希值:

# 进入Django Shell执行:python manage.py shell
from your_app.models import UserTable
from django.contrib.auth.hashers import make_password

for user in UserTable.objects.all():
    # 判断是否已为哈希值(Django哈希以pbkdf2_sha256$开头)
    if not user.password.startswith('pbkdf2_sha256$'):
        user.password = make_password(user.password)
        user.save()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:08:29