Auth认证模块
# auth模块
auth的认证依赖于 auth_user 表! Django的admin也是基于这张表的.
auth模块常用方法归纳参考链接: https://www.cnblogs.com/Dominic-Ji/p/10881136.html
为了实验,用createsuperuser命令先创建一个超级用户!!
该超级用户会记录在 auth_user 表中, 并且密码是加密的!!
from django.shortcuts import render, redirect, HttpResponse
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User # -- 指的就是auth_user这张表!!
def home(request):
return HttpResponse('欢迎来到首页!')
def login(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# -- ▲ auth.authenticate() 提供了用户认证功能
# 即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数 request可不传.
# 它会自动把用户输入的密码加密,再去user_auth表中进行比对.
# ★ 若认证成功(用户名和密码正确有效),便会返回一个User对象!! 认证失败,返回None!!
user_obj = auth.authenticate(request, username=username, password=password)
# print(user_obj) # egon -- 说明auth_user表对应的model类实现了__str__方法.
# -- 若用户认证成功,开始登陆
if user_obj:
# -- ▲ auth.login() 实现一个用户登录的功能
# 该函数接受一个HttpRequest对象,以及一个经过认证的User对象
# ★ 该函数的本质是在后端为该用户生成相关session数据!! => 浏览器sessionid;django_session表.
# ★★★ 用户认证+登陆后,才会把user_obj这个user对象赋值给request.user.
# 这样的话,在全局/任何地方都可以通过request.user取出用户对象!
# 否则,request.user取出的是匿名用户AnonymousUser..
# ps: ▲ is_authenticated() 判断是否认证登陆完成
# request.user.is_authenticated() 返回bool值;
# ★ 其实直接看request.user是否是用户对象就能判断啦!
auth.login(request, user_obj)
# Redirect to a success page.
return redirect('/home/')
else:
# Return an 'invalid login' error message.
pass
return render(request, 'login.html')
# -- ▲ login_required 该装饰器工具用来快捷的给某个视图添加登录校验
# 若没有登陆,跳转的默认登陆路由是'/accounts/login/?next=/order/',有两种解决方案.
# 方案一. 添加login_url参数指定跳转的登陆路由!!
# 方案二.
# @login_required 装饰视图
# LOGIN_URL = '/login/' # 这里settings.py里配置项目登录页面的路由
@login_required(login_url='/login')
def order(request):
return HttpResponse('欢迎来到订单页面!')
@login_required(login_url='/login')
def set_password(request):
# ★★★ 用户认证登陆成功后,在全局/任何地方都可以通过request.user取出用户对象!
user = request.user
if request.method == 'POST':
old_pwd = request.POST.get('old_password', '')
new_pwd = request.POST.get('new_password', '')
re_pwd = request.POST.get('repeat_password', '')
# -- ▲ check_password(password) 检查密码是否正确的方法,需要提供当前请求用户的密码
# 密码正确返回True,否则返回False
is_right = user.check_password(old_pwd) # -- 判断老密码是否正确
if is_right:
# -- 判断两次密码是否一致,若一致则开始修改密码
if new_pwd == re_pwd:
# -- ▲ set_password() 修改密码的方法,接收要设置的新密码作为参数
# ★★★ 注意:设置完一定要调用用户对象的save方法!!!
user.set_password(new_pwd) # -- 这一行并没有操作数据库
user.save() # -- 这一行才开始真正的操作数据库
return redirect("/login/") # -- 修改完成后跳转登陆页面
return render(request, 'set_password.html')
@login_required(login_url='/login')
def logout(request):
# -- ▲ logout() 注销登陆功能
# 该函数接受一个HttpRequest对象,无返回值
# 当调用该函数时,当前请求的session信息会全部清除.
# 该用户即使没有登录,使用该函数也不会报错.
auth.logout(request)
return redirect('/home/')
# -- 注册
def register(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
# -- 入库
# -- ▲ create_user() 创建新用户的方法,需要提供必要参数(username、password)等.
# ps: User表的字段
# is_staff: 用户是否拥有网站的管理权限
# is_active: 是否允许用户登录,设置为False,可以在不删除用户的前提下禁止用户登录
# User.objects.create(username=username, password=password) # -- 数据库中密码是明文的
# -- 内部有个make_password方法,对密码进行了加密!
User.objects.create_user(username=username, password=password) # -- 数据库中密码是密文的
return render(request, 'register.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 扩展auth_user表
这内置的认证系统这么好用, 但是auth_user表字段都是固定的那几个.
若想要加一个存储用户手机号的字段, 怎么办?
很容易想到新建另外一张表然后通过一对一和内置的auth_user表关联!!
这样虽然能满足要求但是有没有更好的实现方式呢?我们可以通过继承内置的 AbstractUser 类,来定义一个自己的Model类
这样既能根据项目需求灵活的设计用户表,又能使用Django强大的认证系统!!
大前提: 一旦执行过迁移命令就不能再扩展了!!
1> 想要扩展auth_user表,必须继承AbstractUser
AbstractUser类中的字段不需要动,我们只需要写自己扩展的字段!
2> 必须在settings.py中进行配置 -- AUTH_USER_MODEL = "app01.UserInfo"
# -- app名.新定义的表名!
告诉Django使用新定义的UserInfo表来做用户认证!! 迁移数据库时就不会创建 auth_user表啦!
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
1
2
3
4
5
6
7
2
3
4
5
6
7