6.Auth认证模块
Auth模块是什么
Auth模块是django自带的用户认证模块
在创建好一个django项目之后直接执行数据库迁移命令会自动生成很多表( django_session auth_user )
django在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表(必须是管理员用户才能进入)
创建超级用户(管理员用户)
python3 manage.py createsuperuser
Auth模块常用方法
authenticate()
提供了用户认证功能,即验证用户名及密码是否正确,一般需要username、password两个关键字参数。
如果认证成功(用户名和密码有效),便会返回一个User对象。
authenticate()会在User对象上设置一个属性来表示后端已经认证了该用户,且信息在后面的过程中是需要的。
user_obj = auth.authenticate(request,username=username,password=password) print(user_obj) # 用户对象 yuanxiaojiang print(user_obj.username) # yuanxiaogjiang print(user_obj.password) # pbkdf2_sha256$260000$A8AB1kLbRTFaA2wiC03Tle$FRxhnza/VdZVRhx4FxL6xcutGjBZis1l5q9h0yyglVQ= ''' 1.自动查找auth_user表 2.自动给密码加密再比对 该方法的注意事项 括号内必须同时传入用户名和密码(为你一步就帮你筛选出用户对象) '''
login(HttpRequest,user)
该函数接受一个HttpRequest对象,一个经过认证的User对象。
该函数实现一个用户登陆的功能。本质上会在后端为该用户生成session数据。
# 保存用户状态 auth.login(request,user_obj) # # 类似于request.session[key] = user_obj # 只要执行了该方法,就可以在任何地方通过request.user获取当前登陆的用户对象
logout
该函数接受一个HttpRequest对象,无返回值。
当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。
auth.logout(request) # 类似于request.session.flush()
is_authenticated()
用来判断当前请求是否通过了认证(判断用户是否登陆)
request.user.is_authenticated
login_requierd()
auth 给我们提供的一个校验用户是否成功的装饰器工具
from django.contrib.auth.decorators import login_required # 局部配置 @login_required(login_url='/login/') 用户没有登陆则跳转到login_url参数指定的网址 # 全局配置 @login_required 需要在配置文件中(settings.py)对LOGIN_URL进行配置
LOGIN_URL = '/login/' # 这里配置成项目登陆页面的路由
create_user()
auth 提供的一个创建新用户的方法,需要提供必要参数(username、password)等。
# 操作auth_user表写入数据 User.objects.create(username=username,password=password) # 写入数据,不能用create,密码没有进行加密 # 创建普通用户 User.objects.create_user(username=username,email='123.@qq.com',password=password)
create_superuser()
auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等。
# 创建超级用户(了解):使用带代码创建超级用户,邮箱必须填,而用命令行可以不填 User.objects.create_superuser(username=username,email='123@qq.com',password=password)
check_password(password)
auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码,密码正确返回True,否则返回False。
request.user.check_password(password)
set_password(password)
auth 提供的一个修改密码的方法,接收 要设置的新密码 作为参数。
注意:设置完一定要调用用户对象的save方法!!!
request.user.set_password(new_password) # 仅仅是在修改对象的属性 request.user.save() # 这才是真正的操作数据库
User对象的属性
User对象属性:username, password
is_staff : 用户是否拥有网站的管理权限.
is_active : 是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录。
案例
<body> <form action="" method="post"> {% csrf_token %} <p>username: <input type="text" name="username"></p> <p>password: <input type="text" name="password"></p> <input type="submit"> </form> </body>
<body> <form action="" method="post"> {% csrf_token %} <p>username: <input type="text" name="username" disabled value="{{ request.user.username }}"></p> <p>old_password: <input type="text" name="old_password"></p> <p>new_password: <input type="text" name="new_password"></p> <p>confirm_password: <input type="text" name="confirm_password"></p> <input type="submit"> </form> </body>
<body> <form action="" method="post"> {% csrf_token %} <h3>注册</h3> <p>username: <input type="text" name="username"></p> <p>password: <input type="text" name="password"></p> <input type="submit"> </form> </body>
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), # 登陆功能 re_path(r'^login/', views.login), # 校验用户是否登陆 re_path(r'^home/', views.home), re_path(r'^index/', views.index), # 修改密码 re_path(r'^set_password/', views.set_password), # 注销功能 re_path(r'^logout/', views.logout), # 注册功能 re_path(r'^register/', views.register) ]
from django.shortcuts import render,HttpResponse,redirect # Create your views here. '''使用auth模块要用就用全套''' from django.contrib import auth def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 去用户表中校验数据 # 1.表如何获取 # 2.密码如何比对 user_obj = auth.authenticate(request,username=username,password=password) print(user_obj) # 用户对象 yuanxiaojiang print(user_obj.username) print(user_obj.password) ''' 1.自动查找auth_user表 2.自动给密码加密再比对 该方法注意事项 括号内必须同时传入用户名和密码(为了一步就帮你筛选出用户对象) ''' # 判断当前用户是否存活 if user_obj: # 保存用户状态 auth.login(request,user_obj) # 类似于request.session[key] = user_obj # 只要执行了该方法,就可以在任何地方通过request.user获取当前登陆的用户对象 return redirect('/home/') return render(request,'login.html') from django.contrib.auth.decorators import login_required # @login_required(login_url='/login/') # 局部配置:用户没有登陆则跳转到login_url参数指定的网址 @login_required # 全局配置 # @login_required(login_url='/xxx/') # 优先级 局部 > 全局 def home(request): """用户登陆之后才能看到home页面""" print(request.user) # 如果用户登陆了则返回的是用保护对象,没有登陆则返回的是AnonymousUser匿名用户 # 判断用户是否登陆 print(request.user.is_authenticated) # 自动去django_session表里面查找对应的用户对象并给你封装到request.user中 return HttpResponse('home页面') # @login_required(login_url='/login/') @login_required # @login_required(login_url='/xxx/') def index(request): return HttpResponse('index页面') @login_required def set_password(request): if request.method == 'POST': old_password = request.POST.get('old_password') new_password = request.POST.get('new_password') confirm_password = request.POST.get('confirm_password') # 先校验两次密码输入是否一致 if new_password == confirm_password: # 校验老密码是否正确 is_right = request.user.check_password(old_password) # 自己加码比对 if is_right: # 修改密码 request.user.set_password(new_password) # 仅仅是在修改对象的属性 request.user.save() # 这才是真正的操作数据库 return redirect('/login/') return render(request,'set_password.html',locals()) @login_required def logout(request): auth.logout(request) # 类似于request.session.flush() 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') # 操作auth_user表写入数据 # User.objects.create(username=username,password=password) # 写入数据,不能用create,密码没有进行加密 # 创建普通用户 User.objects.create_user(username=username,email='123.@qq.com',password=password) # 创建超级用户(了解):使用带代码创建超级用户,邮箱必须填,而用命令行可以不填 # User.objects.create_superuser(username=username,email='123@qq.com',password=password) return render(request,'register.html')
扩展默认的auth_user表
auth_user表中字段是固定的,如果想要存储用户的手机字段怎么办?
第一种:新建另一张表然后通过一对一关系和内置的auth_user表关联
from django.db import models from django.contrib.auth.models import User class UserDetail(models.Model): phone = models.BigIntegerField() user = models.OneToOneField(to='User')
第二种:面向对象的继承
from django.db import models from django.contrib.auth.models import User,AbstractUser class UserInfo(AbstractUser): """ 如果继承了AbstractUser 那么在执行数据库迁移命令的时候auth_user表就不会再创建出来了 而UserInfo表中会出现auth_user所有的字段外加自己扩展的字段 这么做的好处在于你能够直接点击你自己的表更加快速的完成操作及扩展 前提: 1.在继承之前没有执行过数据库迁移命令 auth_user没有被创建,如果当前库已经创建了那么你就重新换一个库 2.继承的类里面不要覆盖AbstractUser里面的字段名 表里面有的字段都不要动,只扩展额外字段即可 3.需要在配置文件中告诉django你要用UserInfo替代auth_user(******) AUTH_USER_MODEL = 'app01.UserInfo' '应用名.表名' """ phone = models.BigIntegerField() """ 你如果自己写表替代了auth_user那么 auth模块的功能还是照常使用,参考的表页由原来的auth_user变成了UserInfo """