如何在使用自定义认证的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
相关产品推荐
相关产品推荐

