Auth认证系统可分为:用户信息、用户权限、用户组
1.内置User实现用户管理
注册、登录、修改密码、注销使用模型User
1. 建立新的APP,迁移数据库
2. MyDjango和APP中设置urls
from django.urls import path, include
urlpatterns = [
# path('', admin.site.urls),
path('', include(('user.urls', 'user'), namespace='user')),
]
#APP中的urls
from django.urls import path
from user.views import loginView, registerView, setpsView, logoutView
urlpatterns = [
path('regiter.html',registerView,name = 'regiter'),
path('login.html',loginView,name = 'login'),
path('steps.html',setpsView, name = 'steps'),
path('logout.html',logoutView,name = 'logout'),
]
3.模板文件user.html
<!DOCTYPE html>
<html>
<head>
{% load static %}
<title>{{ title }}</title>
<link rel="stylesheet" href="{% static "css/reset.css" %}" />
<link rel="stylesheet" href="{% static "css/user.css" %}" />
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "js/user.js" %}"></script>
</head>
<body>
<div class="page">
<div class="loginwarrp">
<div class="logo">{{ pageTitle }}</div>
<div class="login_form">
<form id="Login" name="Login" method="post" action="">
{% csrf_token %}
<li class="login-item">
<span>用户名:</span>
<input type="text" name="username" class="login_input">
<span id="count-msg" class="error"></span>
</li>
<li class="login-item">
<span>密 码:</span>
<input type="password" name="password" class="login_input">
<span id="password-msg" class="error"></span>
</li>
{% if password2 %}
<li class="login-item">
<span>新密码:</span>
<input type="password" name="password2" class="login_input">
<span id="password-msg" class="error"></span>
</li>
{% endif %}
<div>{{ tips }}</div>
<li class="login-sub">
<input type="submit" name="Submit" value="确定">
</li>
</form>
</div>
</div>
</div>
<script type="text/javascript">
window.onload = function() {
var config = {
vx : 4,
vy : 4,
height : 2,
width : 2,
count : 100,
color : "121, 162, 185",
stroke : "100, 200, 180",
dist : 6000,
e_dist : 20000,
max_conn : 10
};
CanvasParticle(config);
}
</script>
<script src="{% static "js/canvas-particle.js" %}"></script>
</body>
</html>
4.分别定义注册、登录、修改密码、注销的views.py
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.shortcuts import render
import user
def registerView(request):
title = '注册'
pageTitle = '用户注册'
if request .method =='POST':
u = request.POST.get('username','')
p = request.POST.get('password','')
if User.objects.filter(username=u):
tips = '用户已存在'
else:
d = dict(username = u,password = p,is_staff = 1,is_superuser = 1)
user = User.objects.create_user(**d)
user.save()
tips = '注册成功,请登录'
return render(request,'user.html',locals())
def loginView(request):
title = '登录'
pageTitle = '用户登录'
if request.method=='POST':
u = request.POST.get('username','')
p = request.POST.get('password','')
if User.objects.filter(username=u):
user = authenticate(username = u,password = p)
if user:
if user.is_active:
login(request,user)
return HttpResponse('登录成功')
else:
tips = '账号密码错误,请重新输入'
else:
tips = '用户不存在,请注册'
return render(request,'user.html',locals())
def setpsView(request):
title = '修改密码'
pageTitle = '修改密码'
password2 = True
if request.method == 'POST':
u = request.POST.get('username','')
p = request.POST.get('password','')
p2 = request.POST.get('possword2','')
if User.objects.filter(username=u):
user = authenticate(username = u,password = p)
if user:
user.set_password(p2)
user.save()
tips = '密码修改成功'
else:
tips = '原始密码不对'
else:
tips = '用户不存在'
return render(request,'user.html',locals())
from django.contrib.auth.hashers import make_password
def setpsView2(request):
# 设置模版上下文
title = '修改密码'
pageTitle = '修改密码'
password2 = True
if request.method == 'POST':
u = request.POST.get('username', '')
p = request.POST.get('password', '')
p2 = request.POST.get('password2', '')
# 判断用户是否存在
user = User.objects.filter(username=u)
if User.objects.filter(username=u):
user = authenticate(username=u,password=p)
# 判断用户的账号密码是否正确
if user:
# 密码加密处理并保存到数据库
dj_ps = make_password(p2, None, 'pbkdf2_sha256')
user.password = dj_ps
user.save()
else:
print('原始密码不正确')
return render(request, 'user.html', locals())
def logotView(request):
logout(request)
return HttpResponse('注销成功')
2.发送邮件实现密码找回
以QQ邮箱为例;
1. 在QQ邮箱设置中找到
2. 开启POP/SMTP服务,并记住保存授权密码
3. 在settings.py文件中配置
# 邮件配置信息
EMAIL_USE_SSL = True
# 邮件服务器,如果是 163就改成 smtp.163.com
EMAIL_HOST = 'smtp.qq.com'
# 邮件服务器端口
EMAIL_PORT = 465
# 发送邮件的账号
EMAIL_HOST_USER = '185231027@qq.com'
# SMTP服务密码
EMAIL_HOST_PASSWORD = 'odnwdcwsphzib'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
4.配置路由在MyDjango和APP中分别配置
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(('user.urls', 'user'), namespace='user')),
]
from django.urls import path
from user.views import loginView, registerView, setpsView, logoutView, findpsView
urlpatterns = [
path('',findpsView,name = 'findps')
]
5.修改模板文件user.html
<!DOCTYPE html>
<html>
<head>
{% load static %}
<title>找回密码</title>
<link rel="stylesheet" href="{% static "css/reset.css" %}" />
<link rel="stylesheet" href="{% static "css/user.css" %}" />
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "js/user.js" %}"></script>
</head>
<body>
<div class="page">
<div class="loginwarrp">
<div class="logo">找回密码</div>
<div class="login_form">
<form id="Login" name="Login" method="post" action="">
{% csrf_token %}
<li class="login-item">
<span>用户名:</span>
<input type="text" name="username" class="login_input">
<span id="count-msg" class="error"></span>
</li>
{% if password %}
<li class="login-item">
<span>密 码:</span>
<input type="password" name="password" class="login_input">
<span id="password-msg" class="error"></span>
</li>
{% endif %}
{% if VCodeInfo %}
<li class="login-item">
<span>验证码:</span>
<input type="text" name="VCode" class="login_input">
<span id="password-msg" class="error"></span>
</li>
{% endif %}
<div>{{ tips }}</div>
<li class="login-sub">
<input type="submit" name="Submit" value="{{ button }}">
</li>
</form>
</div>
</div>
</div>
<script type="text/javascript">
window.onload = function() {
var config = {
vx : 4,
vy : 4,
height : 2,
width : 2,
count : 100,
color : "121, 162, 185",
stroke : "100, 200, 180",
dist : 6000,
e_dist : 20000,
max_conn : 10
};
CanvasParticle(config);
}
</script>
<script src="{% static "js/canvas-particle.js" %}"></script>
</body>
</html>
6.写views.py
import random
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
# 找回密码
def findpsView(request):
button = '获取验证码'
VCodeInfo = False
password = False
if request.method == 'POST':
u = request.POST.get('username')
VCode = request.POST.get('VCode', '')
p = request.POST.get('password')
user = User.objects.filter(username=u)
# 用户不存在
if not user:
tips = '用户' + u + '不存在'
else:
# 判断验证码是否已发送
if not request.session.get('VCode', ''):
# 发送验证码并将验证码写入session
button = '重置密码'
tips = '验证码已发送'
password = True
VCodeInfo = True
VCode = str(random.randint(1000, 9999))
request.session['VCode'] = VCode
user[0].email_user('找回密码', VCode)
# 匹配输入的验证码是否正确
elif VCode == request.session.get('VCode'):
# 密码加密处理并保存到数据库
dj_ps = make_password(p, None, 'pbkdf2_sha256')
user[0].password = dj_ps
user[0].save()
del request.session['VCode']
tips = '密码已重置'
# 输入验证码错误
else:
tips = '验证码错误,请重新获取'
VCodeInfo = False
password = False
del request.session['VCode']
return render(request, 'user.html', locals())
3.模型User的扩展与使用
- 代理模型:是一种模型继承,在数据库中无需创建新数据表。一般用于改变现有模式的行为方式,如增加新方法函数等,且不影响数据表的结构。
- Profile扩展模型User:当存储信息与模型User相关,而且不改变模型User的内置方法时,可定义新的模型MyUser,并设置某个字段为OneToOneField,这样能与模型User形成一对一关系,该方法称为用户配置。
- AbstractBaseUser扩展模型:当模型User的内置方法不符合开发需求时,可使用该方法对模型User重新自定义设计,该方法对模型User和数据表结构造成较大影响。
- AbstractUserUser扩展模型:如果模型User的内置方法符合开发需求,且在不改变这些函数方法的情况下,添加模型User的额外字段,可通过使用AbstractUser方式替换原有的User模型。
4.权限设置与使用
用户、用户权限、用户组的三者关系,无论如何设置,本质是对两个数据表之间的数据建立多对多的数据关系:
- 数据表user_mysuer_user_permissions:管理数据表user_myuser和auth_permissions之间的多对多关系,设置用户所拥有的权限。
- 数据表user_myuser_groups:管理数据表user_myuser和auth_group之间的多对多关系,设置用户所在的用户组。
- 数据表auth_group_permissions:管理数据表auth_group和auth_permission之间多对多关系,设置用户组所拥有的权限。
5.设置网页的访问权限
- login_required:用于设置用户登录访问权限。如果当前用户在尚未登录的状态下访问用户页面中心,程序就会自动跳转到用户登录页面,只有用户完成登录后才能正常访问用户中心。
- permission_required用于验证当前用户是否拥有相应的权限。若用户不具备权限,则程序跳转到指定的路由地址或者抛出异常 。