Auth模块
Auth模块
- Auth模块是Django自带的功能强大的用户认证模块.
- Auth可以实现包括用户的注册, 登录, 注销, 认证, 密码管理等功能
- Auth用户认证系统默认使用 auth_user 表来存储用户数据
- 在使用auth模块之前需要先执行数据库迁移命令生成auth_user表
- python manage.py makemigrations
- python manage.py migrate
- 创建超级用户
- python manage.py createsuperuser
- 创建的用户就存储在auth_user中
- 可以登录admin管理系统
- 使用auth模块需要导入
- from django.contrib import auth
- 使用auth模块最好用全套功能
Auth模块的基本功能
auth.authenticate(request, username=None, password=None, **kwargs)
- 提供用户的登录认证功能, 验证用户的用户名与密码是否正确
- 如果认证成功, 会返回一个user对象,反之返回None
- 该方法自动查找auth_user表,自动给密码加密再比对
from django.shortcuts import render
from django.contrib import auth
def login(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# 使用auth验证用户的账号密码 验证成功返回用户对象,不成功返回None
user_obj = auth.authenticate(request, username=username, password=password)
print(user_obj.username, user_obj.password)
# wcy
# pbkdf2_sha256$150000$07rw645esC4g$USgBuXVAVsjR/bCojJ7aePuw08EJHPQ5YcPAjOgl9TA=
# 返回的密码是密文
return render(request, 'login.html')
auth.login(request, user, backend=None)
- 该方法需要传入request, user对象,在验证成功后使用
- 该方法会自动操作django_session表,记录用户的登陆状态
- 相当于request.session[key] = value
- 只要执行了该方法,就可以在任何地方通过request.user获取到当前登陆的用户对象
request.user
- 获取登陆的用户对象
- 如果没有登陆访就问该页面 返回AnonymousUser
request.user.is_authenticated
- 验证用户是否登陆
- 返回bool值
request.user.is_anonymous
- 该属性判断一个用户是否是匿名用户, 返回一个布尔值. 与is_authenticated相反.
user对象其他的字段属性
username 用户名, 必须填写
password 密码字段, 以密文存储.
email 邮箱字段
is_staff bool类型, 判断用户是否允许登录admin_site
is_active 用户是否是激活状态
is_superuser 是否是超级管理员
def login(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# 使用auth验证用户的账号密码 验证成功返回用户对象,不成功返回None
user_obj = auth.authenticate(request, username=username, password=password)
# print(user_obj.username, user_obj.password)
if user_obj:
auth.login(request, user_obj)
return redirect('/home/')
return render(request, 'login.html')
def home(request):
# 获取登陆的用户对象 wcy
# 如果没有登陆访问该页面 返回AnonymousUser
print(request.user)
# 验证是否登陆
print(request.user.is_authenticated)
return HttpResponse('登陆成功')
login_requierd()
- from django.contrib.auth.decorators import login_required
- 这个方法是一个登录装饰器, 它能帮我们为一些视图函数提供登录验证.
- 如果用户没有登录, 这个登录用户会让用户自动跳转到登录的页面.
- Django默认的登录页面的URL为/accounts/login/, 这时候我们需要配置登录的URL
- 局部配置:在每一个需要登录的视图上指定跳转的登录url.
login_requierd(login_url='/login/')
- 全局配置:settings文件中添加
LOGIN_URL = '/login/'
- 局部配置的优先级比全局配置高,会优先跳转到局部配置的页面
@login_required(login_url='/login/')
def home(request):
# 获取登陆的用户对象 wcy
# 如果没有登陆访问该页面 返回AnonymousUser
print(request.user)
# 验证是否登陆
print(request.user.is_authenticated)
# 是否匿名用户
print(request.user.is_anonymous)
return HttpResponse('登陆成功')
全局配置后直接添加装饰器即可
@login_required
def home(request):
# 获取登陆的用户对象 wcy
# 如果没有登陆访问该页面 返回AnonymousUser
print(request.user)
# 验证是否登陆
print(request.user.is_authenticated)
# 是否匿名用户
print(request.user.is_anonymous)
return HttpResponse('登陆成功')
修改密码相关
request.user.check_password(raw_password)
- 校验密码
- 提供原来的密码来到数据库中进行比对, 正确则返回True, 错误则返回False
request.user.set_password(raw_password)
- 修改密码, 需要接受新的的密码为参数
- 修改之后要使用request.user.save()保存,不然修改无效
@login_required
def set_password(request):
if request.method == "POST":
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
again_password = request.POST.get('again_password')
if request.user.check_password(old_password): # 判断旧密码是否正确
if new_password == again_password: # 比较两次输入新密码
request.user.set_password(new_password) # 修改密码
request.user.save()
return HttpResponse('修改成功')
return render(request, 'set_passeord.html', locals())
完整视图函数
from django.shortcuts import render, redirect, HttpResponse
from django.contrib import auth
from django.contrib.auth.decorators import login_required
# Create your views here.
def login(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# 使用auth验证用户的账号密码 验证成功返回用户对象,不成功返回None
user_obj = auth.authenticate(request, username=username, password=password)
# print(user_obj.username, user_obj.password)
if user_obj:
auth.login(request, user_obj)
if request.GET.get('next'):
return redirect(request.GET.get('next')) # 上次的路径在next参数中
return redirect('/home/')
return render(request, 'login.html')
@login_required
def home(request):
# 获取登陆的用户对象 wcy
# 如果没有登陆访问该页面 返回AnonymousUser
print(request.user)
# 验证是否登陆
print(request.user.is_authenticated)
# 是否匿名用户
print(request.user.is_anonymous)
return HttpResponse('登陆成功')
@login_required
def set_password(request):
if request.method == "POST":
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
again_password = request.POST.get('again_password')
if request.user.check_password(old_password):
if new_password == again_password:
request.user.set_password(new_password)
request.user.save()
return HttpResponse('修改成功')
return render(request, 'set_passeord.html', locals())
注销
logout(request)
- 接收一个request对象, 将该用户在session表中的信息清除掉
- 相当于request.session.flush()
- 即使用户没有登录, 使用这个方法也不会报错.
注册
- 使用注册方法要先导入auth_user表
from django.contrib.auth.models import User
User.objects.create_user(username, email=None, password=None, **extra_fields)
- 这个创建用户的方法能够自动使用set_password()来创建新用户保存到数据库中.
- 而如果使用orm原来的create方法, 则会使用明文保存到数据库中.后面使用auth模块会无法正确比对密码
User.objects.create_superuser(username, email=None, password=None, **extra_fields)
- 方法功能与create_user一样, 只不过这个方法是创建超级用户.
- 使用该方法创建超级用户必须要email参数,使用命令行创建不需要
@login_required
def logout(request):
auth.logout(request) # 注销
return redirect('/login/')
from django.contrib.auth.models import User
def register(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# 创建普通用户
User.objects.create_user(username=username, password=password)
# 创建超级用户
# 必须要email字段
# User.objects.create_superuser(username=username, password=password, email='123@qq.com')
return redirect('/login/')
return render(request, 'register.html')
auth表的扩建
auth_user表的扩建
- 扩建方式
- 方式一:创建一张表使用一对一关系关联到User(不推荐)
class UserDetail(models.Model)
user = models.OneToOneField(to='User', on_delete=models.CASCADE)
- 方式二:面向对象继承
- 重新在models.py创建一张表继承AbstractUser类
- from django.contrib.auth.models import AbstractUser
- 在自己创建的表中,可以扩展字段,但是不要动原来有的字段
- 如果想要使用自己创建的表,必须满足一下条件
- 当前数据库没有执行数据库迁移命令,如果已经执行过,就重新连接一个数据库
- 不要覆盖原来的字段名
- 在配置文件中配置自己的auth表
- AUTH_USER_MODEL = 'app01.UserInfo' # 应用名.表名
- 在配置完成后,执行数据库迁移命令,将不会生成原来的auth_user表,而是自己创建的表
- 后序使用就导入自己创建的表即可
- auth表功能依旧不变,完全可以正常使用,这就是方便的地方
class UserInfo(AbstractUser):
phone = models.CharField(max_length=11)
create_data = models.DateField(auto_now_add=True)