【Django基础】auth认证模块

发布时间 2023-11-24 17:43:34作者: 小C学安全

https://www.cnblogs.com/DuoDuosg/p/17005583.html
一、django的auth认证模块
1.什么是auth模块
Auth模块是Django自带的用户认证模块:

我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

2.生成auth物理表
使用auth组件前,一定要切记生成物理表(进行数据迁移)

前戏:django自带一个admin路由,但是需要提供账户和密码
如果想要使用admin后台管理,需要创建表,然后创建管理员账户,和django_session一样,执行迁移命令后,会出现一张auth_user表。

auth_user表,该表就是admin默认的后台表,就是Django自带的用户认证模块用来存储用户数据的表

python manage.py makemigrations
python manage.py migrate
image-20221226000546189
二、创建django-admin账户
1.创建超级管理员
在终端中执行命令,创建超级管理员

不能在表中直接创建,由于密码是需要加密的,而表中创建则不会通过auth模块加密,在使用的时候,密码比对会发生错误

python manage.py createsuperuser
2.注册超级管理员账户
在终端中注册超级管理员账户

image-20221226000902990
image-20221226001212824

3.登录admin账户
三、auth模块中的方法
普通用户注册只能通过逻辑来编写

不能自己创建,因为密码加密无法实现

image-20221223105141577

1.导入auth模块以及导入User表

导入auth模块

from django.contrib import auth

导入auth-user表

from django.contrib.auth.models import User
通过导入的User,就可以通过orm来操作这张表

2.create_user
image-20221226111359695

image-20221226111516579

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

def register_func(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
# 1。校验用户是否已经存在
res = User.objects.filter(username=username)
if res:
return HttpResponse("该用户名已经存在")
# 2。注册该用户
User.objects.create(username=username, password=password)
return render(request, 'register.html')
所以我们通过ORM的create方法,不能操作auth_user表,需要用create_user方法来创建加密密码的普通用户

image-20221226111943191

image-20221226112028028

1.auth.authenticate校验用户是否已经存在
通过authenticate方法

校验用户成功后,返回的是一个封装好的用户对象
校验错误则返回None
image-20221226113006679

2.auth.login
用户登录成功之后,返回给客户端登录的凭证或者说是令牌、随机字符串,则不需要我们去操作diango_session表,会自动创建session

def login_func(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# 1。通过auth模块来校验加密后的密码
user_obj = auth.authenticate(request, username=username, password=password)
if user_obj:
# 2.用户登录成功之后(返回给客户端登录的凭证或者说是令牌、随机字符串)
auth.login(request, user_obj) # 自动操作django_session表
return render(request, 'loginPage.html')
image-20221226113927603

image-20221226113958307

3.request.user
当执行完auth.authenticate和auth.login后,也就是登录成功后,我们就可以通过request.user直接获取到当前登录的用户对象数据

登录成功的情况下,该方法获得的是登录用户对象
登录不成功的情况下,该方法获得的是匿名对象AnonymousUser
image-20221226115124930

4.request.user.is_authenticated判断当前对象,是否已登录
该对象是登录的用户对象返回True,否则返回False

由于匿名对象和登录对象,直接if判断,返回的都是True,所以可以通过该方法,进一步判断是否是登录对象

image-20221226115527828

该方法可以用在前端页面上,和模版语法一起使用

image-20221226120222710

image-20221226120358529

四、基于auth_user表编写用户相关的各项功能
1.注册
def register_func(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
# 1。校验用户是否已经存在
res = User.objects.filter(username=username)
if res:
return HttpResponse("该用户名已经存在")
# 2。注册该用户
# User.objects.create(username=username, password=password)
User.objects.create_user(username=username, password=password)
return render(request, 'register.html')
2.登录

auth_user表校验登录用户

def login_func(request):
print(request.user)
print(request.user.is_authenticated)
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# 1。通过auth模块来校验加密后的密码
user_obj = auth.authenticate(request, username=username, password=password)
if user_obj:
# 2.用户登录成功之后(返回给客户端登录的凭证或者说是令牌、随机字符串)
auth.login(request, user_obj) # 自动操作django_session表
return HttpResponse('登录成功')
return render(request, 'loginPage.html')
3.auth校验用户是否登录装饰器
from django.contrib.auth.decorators import login_required

@login_required
def XXX(request):pass
image-20221226121349501

我们可以自定义未登录后跳转的路由地址,有以下两种方式

全局配置

在settings中,配置未登录后跳转的路由

LOGIN_URL = '/login/'
局部配置

在装饰器后填写login_url='XXX'

image-20221226121849920

当全局和局部都配置了时候,局部的优先级高于全局

4.auth用户修改密码
校验原密码是否正确

request.user.check_password(原密码)

修改密码

request.user.set_password(新密码)
request.user.save()

def set_pwd_func(request):
if request.method == "POST":
old_pwd = request.POST.get("old_pwd")
new_pwd = request.POST.get("new_pwd")
confirm_pwd = request.POST.get("confirm_pwd")
# 小判断
if not confirm_pwd == new_pwd:
return HttpResponse("两次密码不一致")
# 1。校验用户密码
is_right = request.user.check_password(old_pwd)
if not is_right:
return HttpResponse('原密码输入错误')
# 2。修改密码
request.user.set_password(new_pwd)
request.user.save() # 修改之后必须要保存,不然不会修改
return render(request, 'setPwdPage.html')
request.user.save() 修改之后必须要保存,不然不会修改成功
5.退出登录
auth.logout(request)退出登录
退出登录的本质就是删除session表中相关的数据

@login_required
def logout_func(request):
auth.logout(request)
return HttpResponse("退出登录成功")
image-20221226125118761

image-20221226125321964

五、扩展auth_user表
1.思路1:一对一字段关联auth_user表
在models.py中创建一张模型表,与之关联auth_user表

models.py中
from django.contrib.auth.models import User

class OtherUser(models.Model):
user = models.OneToOneField(to=User)
但是这样做较为繁琐,不推荐

2.思路2:替换auth_user表
(1)首先导入真正的auth_user表

from django.contrib.auth.models import User, AbstractUser
image-20221226130046256

image-20221226130151935

我们可以看到User表是继承了AbstactUser的,而AbstractUser才是真的auth_user表

(2)继承AbstractUser,并编写其中没有的字段

在执行迁移命令前,要确保数据库中没有auth_user表,如果有的话则需要删除表,重新执行迁移命令

在settings.py中配置

告诉ORM,使用app01下的UserInfo表替换原先的auth_user表

AUTH_USER_MODEL = 'app01.UserInfo'
编写新的User表
from django.contrib.auth.models import User, AbstractUser

class UserInfo(AbstractUser):
# 继承AbstractUser,并编写其中没有的字段
phone = models.BigIntegerField()
desc = models.TextField()

image-20221226130935010

则后面使用该表的地方,都需要改成

原先

User.objects.filter()

from app01 import models

现在

models.UserInfo.objects.filter()