Django应用:MySQL中Login模型密码明文转哈希存储求助
Hey there! Let's get that plaintext password storage sorted out for your Login model. Since you already have Django's password hashers configured in settings.py, we can leverage those to store hashed passwords instead. Here's a step-by-step fix:
1. Update Your Login Model
First, adjust the Login model to handle password hashing automatically when saving. We'll use Django's built-in make_password utility and ensure the password field can accommodate hashed values (they're way longer than 32 characters!):
from django.db import models from datetime import datetime from django.contrib.auth.models import User from django.contrib.auth.hashers import make_password # Import the hashing tool class LoginEvent(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) date_and_time = models.DateTimeField(auto_now_add=True) # Swapped DateField for DateTimeField to capture full timestamp def __str__(self): return f"{self.user}: {self.date_and_time}" class Login(models.Model): username = models.CharField(max_length=50) # Increase max_length to fit hashed passwords (255 is safe for all Django hashers) password = models.CharField(max_length=255, default="", null=False) def save(self, *args, **kwargs): # Hash the password before saving to the database self.password = make_password(self.password) super().save(*args, **kwargs) def __str__(self): return self.username
2. Clean Up Your Login View
Next, fix the view logic to ensure the form is handled correctly, and that we only save valid data. I also tidied up the LoginEvent timestamp handling and added proper form validation:
from .models import Login, LoginEvent from django.contrib.auth import authenticate, login from django.shortcuts import render, HttpResponseRedirect, reverse from django.contrib import messages from django import forms # Define your authForm if you haven't already (assuming it's a ModelForm for Login) class authForm(forms.ModelForm): class Meta: model = Login fields = ['username', 'password'] def login_view(request): context = {} if request.method == "POST": authform_data = authForm(request.POST) username = request.POST.get('username') password = request.POST.get('password') # Authenticate using Django's built-in system user = authenticate(request, username=username, password=password) if user: login(request, user) # Only save the Login instance if the form is valid if authform_data.is_valid(): authform_data.save() # The model's save() will hash the password automatically # Log the login event with the correct timestamp LoginEvent.objects.create(user=user) return HttpResponseRedirect(reverse('IP form')) else: messages.error(request, 'Please provide valid credentials') context['form'] = authform_data else: authform_data = authForm() context['form'] = authform_data return render(request, "first_app/login.html", context)
Key Notes:
- Why this works: The
make_passwordfunction uses the first hasher in yourPASSWORD_HASHERSlist (PBKDF2PasswordHasher) by default, which matches your configured settings. - Field length: Hashed passwords are much longer than plaintext, so increasing
max_lengthto 255 ensures we don't truncate any hash values. - Redundancy check: Quick heads up—your
Loginmodel is redundant with Django's built-inUsermodel (which already stores hashed passwords). If you're just tracking logins, theLoginEventmodel (linked toUser) is sufficient. Only keepLoginif you have a specific use case for storing duplicate user credentials.
After making these changes, check your MySQL database's Login table—you should see hashed strings (like pbkdf2_sha256$390000$...) instead of plaintext passwords.
内容的提问来源于stack exchange,提问作者Mystery

