Django登录/认证系统不能正常工作



我是一个新手在django和我有一些问题,我想做的是一个简单的登录系统在django自定义后端和使用postgresql作为主数据库。

问题是,我的身份验证和登录功能显然正常工作,但用户实际上没有登录,我写了一个自定义消息让我知道用户何时登录,我的索引是受匿名用户保护的,所以我基本上无法访问。

这个代码来自myviews.py

@login_required(login_url='signin')
def index(request):
return render(request, 'index.html')
def signin(request):
now = datetime.now()
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
print(username, password)
user = UserBackend.authenticate(UserBackend(), username=username, password=password)
if user is not None:
login(request, user, backend='core.backends.UserBackend')
print('Logged In') #### This print/checking is working fine!
return redirect('/')  
#return render(request, 'index.html')
else:
messages.info(request, 'Invalid Username or Password! Try again')
return redirect("signin")
#else:
return render(request,'signin.html')

#user = auth.authenticate(username=username, password=password)
return render(request, 'signin.html')

这是我的用户类从models.py

class user(AbstractBaseUser):
id = models.AutoField(primary_key=True)
username = models.TextField()
real_name = models.TextField()
email = models.TextField()
password = models.TextField()
description = models.TextField()
last_login = models.DateField()
created_at = models.DateField()
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)

class Meta:
managed = False
db_table = 'user'


def __str__(self) -> str:
return self.username

和我的用户后端从backend .py

class UserBackend(ModelBackend):
def authenticate(self, **kwargs):
username = kwargs['username']
password = kwargs['password']
print('user: ', username)
print('pass: ', password)
#try:
user_ = user.objects.get(username=username)

try:
print(user_.check_password(password))
if user_.check_password(password) is True:
return user_
except user.DoesNotExist:
pass
def get_user(self, user_id):
try:
return user.objects.get(pk=user_id)
except user.DoesNotExist:
return None

我尝试将views.py的返回值更改为

return redirect(request.GET.get('next')) 

但仍不工作:(

我该怎么办?

关键在于如何使用后端。尽管如此,让我们从头开始……

从你的模型开始,你不必要地覆盖了很多字段。Django的AbstractUser有这些你正在创建的字段。实际上,模型在适当的地方包含以下带有验证器的字段:

  1. 用户名
  2. first_name
  3. last_name
  4. is_staff默认为false
  5. is_active默认为true
  6. date_joined为默认timezone.now()
  7. last_login
  8. 一个内置函数get_full_name(相当于你的real_name字段)

另外,id = models.AutoField(primary_key=True)不是必需的,Django默认为每个模型自动创建这种字段。大多数时候,当你想要一个不同类型的字段作为PK。因此一个简单的模型,将满足您的要求:

from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
description = models.TextField()

后端非常直接,检查凭证并返回一个User对象实例,如果一切正确。ModelBackend已经定义了一个get_user方法。

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.hashers import check_password
from django.contrib.auth import get_user_model
User = get_user_model()
class UserBackend(ModelBackend):
def authenticate(self, request, **kwargs):
username = kwargs['username']
password = kwargs['password']

try:
user = User.objects.get(username=username)
pwd_valid = check_password(password, user.password)

if  pwd_valid:
return user
else:
return None

except User.DoesNotExist:
return None

现在,关于如何使用它。引用文档:

在后台,Django维护一个"authentication"列表它检查身份验证的后端。当有人打来电话Django .contrib.auth.authenticate(它的所有身份验证后端。如果采用第一种身份验证方法失败,Django会尝试第二个,以此类推,直到所有后端都失败尝试。

要使用的身份验证后端列表在AUTHENTICATION_BACKENDS设置。这应该是一个Python路径列表指向知道如何进行身份验证的Python类的名称。这些类可以在Python路径的任何位置。

因此,首先我们需要在settings.py: 中添加AUTHENTICATION_BACKENDS:
AUTH_USER_MODEL = 'core.User'
LOGIN_URL = '/signin'
AUTHENTICATION_BACKENDS = [
'core.auth.backends.UserBackend', 
'django.contrib.auth.backends.ModelBackend'
]

最后,在views.py中,我们像调用普通登录函数一样调用这些函数:

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.contrib import messages
# Create your views here.
@login_required
def index(request):
return render(request, 'index.html')
def signin(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Confirm that backend is UserBackend
print(user.backend)
return redirect('core:index')
else:
messages.info(request, 'Invalid Username or Password! Try again')
return redirect("core:signin")
return render(request, 'signin.html')

最新更新