为啥在 Django 的登录表单中显示错误?

Posted

技术标签:

【中文标题】为啥在 Django 的登录表单中显示错误?【英文标题】:Why does it shows error in the log in form in Django?为什么在 Django 的登录表单中显示错误? 【发布时间】:2020-11-18 12:12:01 【问题描述】:

我正在尝试在django中创建一个带有登录和注册表单的网站,注册效果很好,它将帐户保存在数据库中,但是当我尝试登录时,它根本不起作用,这是代码:

views.py

from django.shortcuts import render
from .forms import UserForm
from django.contrib.auth import authenticate, login, logout
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect, HttpResponse


# Create your views here.
def index(request):
    return render(request, 'app1/index.html')

@login_required
def user_logout(request):
    logout(request)
    return HttpResponseRedirect(reverse('index'))

def register(request):

    registered = False

    if request.method == "POST":
        user_form = UserForm(data=request.POST)
        if user_form.is_valid():
            user = user_form.save()
            user.set_password(user.password)
            user.save()

            registered = True
        else:
            print(user_form.errors)
    else:
        user_form = UserForm()

    return render(request, 'app1/register.html','user_form':user_form, 'registered':registered)

def user_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = authenticate(username=username, password = password)

        if user:
            if user.is_active:
                login(request, username)
                return HttpResponseRedirect(reverse('index'))
            else:
                return HttpResponse("Account Not Active")
        else:
            print("Someone tried to login and failed")
            print(f"Username: username and password password")
            return HttpResponse ("Invalid Login details supplied")
    else:
        return render(request, 'app1/login.html')

models.py

from django.db import models
from django.contrib.auth.models import User
# Create your models here.

class UserProfileInfo(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

class UserForm(UserCreationForm):
    email = forms.EmailField(max_length=40, help_text='Required')
    

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

我希望有人可以帮助我,因为我相信错误在views.py中,但我不确定在哪里。

【问题讨论】:

A UserCreationForm 已经对密码进行了哈希处理。 【参考方案1】:

UserCreationForm 已经通过调用set_password 对密码进行了哈希处理,因此再次调用它,将对其进行双重哈希处理。因此,您应该删除 user.set_password(user.password) 行:

def register(request):
    registered = False
    if request.method == 'POST':
        user_form = UserForm(data=request.POST)
        if user_form.is_valid():
            # do not hash a second time
            #  user.set_password(user.password)
            user = user_form.save()
            
            registered = True
        else:
            print(user_form.errors)
    else:
        user_form = UserForm()

    return render(request, 'app1/register.html','user_form':user_form, 'registered':registered)

注意:如果 POST 请求成功,您应该发送redirect [Django-doc] 实施Post/Redirect/Get pattern [wiki]。 这样可以避免在用户刷新时发出相同的 POST 请求 浏览器。

【讨论】:

是的,但问题是,当我尝试登录时,会出现 user_login 函数中的错误,显示提供的登录详细信息无效,它应该让我登录,因为它在数据库中 @SebastianNin: 当然,因为如果你存储一个双哈希密码,那么authenticate 将哈希一次,双哈希密码将与一次哈希密码不匹配。 所以我只需要留下 user = user_form.save()?【参考方案2】:

login 函数中,我们必须传递 user 而不是 username 所以在 user_login 函数中

if user:
    if user.is_active:
        login(request, user)
        return HttpResponseRedirect(reverse('index'))
    else:
        return HttpResponse("Account Not Active")

【讨论】:

以上是关于为啥在 Django 的登录表单中显示错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Django 中的表单中捕获错误?

在每个页面上放置一个 django 登录表单

Django,自定义身份验证登录。身份验证失败时如何显示错误消息?

为啥我的 Django 表单没有引发验证错误?

表单验证 - Django 中的注册和登录错误处理

Django modal Bootstrap 表单的错误处理