Django它内置了强大的用户认证系统:auth;

Auth是Django自带的用户认证模块

Django默认使用auth_user表来存储用户数据(也就是第一次迁移数据库时Django创建的表之一)

这张表就是专门用来配合Auth模块做用户的登录、校验用户是否登录、修改密码、注销登录等功能的。

如果想要使用admin后台管理,需要先创建表,然后创建管理员账号。

直接执行数据库迁移命令即可产生默认的auth_user表,该表就是admin后台管理默认的认证表。

默认的auth_user表:

字段释义
idID
password密码
last_login最后登录时间
is_superuser是否是管理员
username用户名
first_name
last_name
email邮箱
is_staff是否是工作人员
is_active是否激活
date_joined创建时间

auth模块常用的属性和方法:

字段释义
create_user()创建用户和加密密码
auth.authenticate判断用户名和密码
is_authenticated判断用户是否登录
request.user获取当前登录用户
check_password校验密码是否正确
set_password修改密码
auth.logout(request)退出登录
login_required校验用户是否登录装饰器
AbstractUser基于auth扩写

导入auth模块

from django.contrib import auth

在执行auth模块相关操作前要先导入数据库中的表

from django.contrib.auth.models import User

常用方法介绍

1.create_user()用户注册功能(即用户创建)

create()创建的密码是明文的

create_user()创建的密码是经过加密的

User.objects.create_user(username=username, password=password)
from django.contrib.auth.models import User 
1.普通用户 
user = User.objects.create_user(username='用户名',password='密码',...) 
2.管理员用户,必须要有email 
user = User.object.create_superuser(username='用户名',password='密码',email='邮箱',...)

2.is_authenticated()判断用户是否登录

request.user.is_authenticated

如果登陆了,结果为布尔值Ture,否则为False

is_authenticated 前面一定要是 request.user

 

3.auth.authenticate() 用户认证,即验证用户名以及密码是否正确

提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username、password两个关键字参数。

如果认证成功(用户名和密码正确有效),便会返回一个User对象。

authenticate()会在该User对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

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

    # 校验用户是否存在 自己是无法比对,因为密码存入其中加密了,所以需要用到auth模块提供的方法才可以
    obj = auth.authenticate(request,username=username,password=password) # 用户名和密码正确之后返回的是数据对象,反之返回None
    # print(obj.password, obj.username)

    if obj:
        return HttpResponse('登录成功!')
    else:
        return HttpResponse('用户名或密码错误!')

    return render(request,'login.html')

此时,我们便已经完成验证用户账号和密码是否正确的一个功能

其本质还是Django把我们输入的内容拿到了auth_user表中对比,匹对成功了返回一个User对象给我们,只不过这些步骤我们只需要调用一个API就可以是实现。

4.获取登录用户对象数据

request.user

# 用户信息可以在user中用点的方式获取
# reqeust.user.username :查看当前登录的用户名
# request.user.password :查看当前登录的用户密码(加密形式的)

5.校验原密码是否正确

密码正确返回True,否则返回False。但必须在登录之后并且保存了登录Session才能使用

user = request.user.check_password('密码')

6.修改密码

request.user.set_password(新密码)

equest.user.save()

设置完一定要调用用户对象的save方法! 通常在check_password校验之后使用

@login_required
def set_pwd(request):
    if request.method == 'POST':
    user = request.user # 获取当前用户对象
    old_pwd = request.POST.get('old_pwd') # 获取用户输入的旧密码
    new_pwd = request.POST.get('new_pwd') # 获取用户输入的新密码
    confirm_pwd = request.POST.get('confirm_pwd') # 二次确认新密码

    if not new_pwd == confirm_pwd:
        return HttpResponse('两次密码不一致')

    # 判断原密码是否正确
    res = request.user.check_password(old_pwd)
    if not res:
        return HttpResponse('原密码错误!')
    else:
        #修改密码
        request.user.set_password(new_pwd)
        request.user.save() # 将修改后的数据保存在auth_user表中

        auth.login(request,user) # 因为用户信息发生变动,需要修改用户的session数据才能保持登录状态
        return HttpResponse('修改成功!')

    return render(request,'set.html')

7.退出登录

def login_out(request):
    auth.logout(request)
    return HttpResponse('已注销用户!')

当调用该函数时,当前请求的Session信息会被全部清除。即使没有登录,使用该函数也不会报错。
后端清空了当前用户保存的Session信息,也可以理解为没有登录状态了,下次访问某些页面需要重新登录

 


扩展auth_user表

如果我们既想使用auth模块的功能,并且又想扩展auth_user表的字段,有以下两种方式:

思路1:一对一字段关联

因为操作相对繁琐,不建议使用.

思路2:替换auth_user表

我们点进调入的User表查看源码,我们发现他只是继承了AbstractUser模块,然后点进AbstractUser源码,我们发现他就相当于一张模型表,配置了auth需要使用的表的具体内容.因此我们可以自己定义一个模型表,只要导入父类AbstractUser即可自定义功能.

操作简单,推荐使用.

ps:替换还有一个前提,就是数据库迁移没有执行过(auth相关表没有创建),即所在的库必须是第一次执行迁移命令才可以,若是原本有残留会引起异常。

步骤1: 配置settings

在settings.py配置文件中声明替换关系(把表替换成自定义的模型表),告诉Django 使用新定义的 UserInfo 表来做用户认证的表。

# settings.py
# 声明使用自定义表作为用户验证,声明格式为: 应用名.表名,继承使用时需要设置
AUTH_USER_MODEL = 'app.UserInfo'

步2: 配置models

创建一个自定义类并继承AbstractUser类,然后编写 AbstractUser 类中没有的字段并且‘不能冲突’。

from django.db import models 
# 导入AbstractBaseUser类,继承AbstractBaseUser类,基本字段 
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
        # 扩展用户信息表 继承原有的auth_user表字段,填写AbstractUser表中没有的字段
        phone = models.BigIntegerField()
        desc = models.TextField()

最后,执行两条数据库迁移命令。

python manage.py makemigrations
python manage.py migrate