前言
本章主要讲述 【找回密码】 功能的实现
该功能的整个流程简要介绍:
--> 当用户点击登录页面【忘记密码?】时,会链接进入【忘记密码界面】
--> 然后需要输入【邮箱、图形验证码信息】进行找回
--> 点击找回后,会自动向【你的邮箱】发送一条【更改密码邮件】
--> 在邮箱中,点击【更改密码】,会自动链接到【更新密码】界面
--> 更改密码后,重新登陆即正常
本文包含主要知识点:
- 1、captcha图片验证码插件的使用
- 2、js刷新图片验证码
- 3、发送网易邮件,修改密码
环境:
- Pycharm
- python3.6
- mysql 5.7
- django 2.0.13
一、准备工作
1、网易邮箱注册及使用
1.1、网易邮箱注册

1.2、开启POP3/SMTP服务


   
1.3 setting.py中配置

# 发送邮件配置
EMAIL_HOST = 'smtp.126.com' # 发送邮件的邮箱的SMTP服务器,这里用的是163邮箱
EMAIL_PORT = 25 # 发件箱的SMTP服务器端口,默认是25
EMAIL_HOST_USER = 'mikasa0610@126.com' # 发送邮件的邮箱地址
EMAIL_HOST_PASSWORD = '用你之前保存下来的授权码' # 之前保存的授权码
EMAIL_USE_TLS = True # 是否使用TLS安全传输协议(用于在两个通信应用程序之间提供保密性和数据完整性)
EMAIL_USE_SSL = False # 是否使用SSL加密,qq企业邮箱要求使用,163邮箱设置为True的时候会报ssl的错误
2、captcha插件下载及配置
2.1、下载
pip install pillow
pip install django-simple-captcha

2.2、setting.py中配置

2.3、创建captche数据库表
python manage.py migrate

2.4、添加captche路由
# 配置captcha路由
re_path(r'^captcha/', include('captcha.urls'))

二、新增功能项目概览
     



三、user模块具体实现
- 上面已经简要概述了一下,那从这part开始,咱们直接贴代码实现
若大家有疑问,仍旧可以私信或者在评论下方留言哈
1、urls.py
- 这里新增【忘记密码】【校验图片验证码】【更新密码】三路由

# 忘记密码
path('forget_pwd', forget_pwd, name='forget_pwd'),
# 校验图片验证码
path('valid_code', valid_code, name='valid_code'),
# 更新密码
path('update_pwd', update_pwd, name='update_pwd'),
2、views.py
- views.py里对应新增三视图函数,具体逻辑我注释里面写的比较详细了,大家可以看下

def forget_pwd(request):
"""
忘记密码
:param request:
:return:
"""
if request.method == 'GET':
form = CaptchaTestForm()
return render(request, 'user/forget_pwd.html', context={'form': form})
else:
# 获取提交的邮箱,发送邮件,通过发送的邮箱链接设置新的密码
email = request.POST.get('email')
# 给此邮箱发送邮件
result = send_email(email, request)
if result == 1:
return HttpResponse("您好,邮件发送成功!请尽快去邮箱查收。")
def valid_code(request):
"""
校验图片验证码:采用了captcha图片验证码插件
:param request:
:return:
"""
if request.is_ajax():
# 1、拿到页面上的hashkey以及输入的验证码code
key = request.GET.get('key')
code = request.GET.get('code')
# 2、CaptchaStore模型对象:根据key在表里找到对应的验证码数据
captcha = CaptchaStore.objects.filter(hashkey=key).first()
if captcha.response == code.lower():
# 验证码正确
data = {'status': 1}
else:
# 验证码错误
data = {'status': 0}
return JsonResponse(data)
def update_pwd(request):
"""
更新密码
:param request:
:return:
"""
if request.method == 'GET':
c = request.GET.get('c')
return render(request, 'user/update_pwd.html', context={'c': c})
else:
# 拿到页面的code
code = request.POST.get('code')
# 拿到之前保存在session里面的code
uid = request.session.get(code)
# 根据code查询数据库对应的用户数据
user = UserProfile.objects.get(pk=uid)
# 获取密码
pwd = request.POST.get('password')
repwd = request.POST.get('repassword')
if pwd == repwd and user:
pwd = make_password(pwd)
user.password = pwd
user.save()
return render(request, 'user/update_pwd.html', context={'msg': '用户密码更新成功,请重新登陆!'})
else:
return render(request, 'user/update_pwd.html', context={'msg': '用户密码更新失败!'})
3、utils.py
- 之前说了这里是一个工具类,因为我们这里用到了发送网易邮件,那这个方法的话,我们也统一封装在这个类里,然后views那边直接调用即可

def send_email(email, request):
"""
发送邮件:给网易126邮箱
:return:
"""
subject = 'Mikasa个人博客找回密码'
# 通过邮箱号查找到对应的用户数据
user = UserProfile.objects.filter(email=email).first()
# 让加密后的uuid等于用户id,并保存在session中
ran_code = uuid.uuid4()
print("替换前:", ran_code)
ran_code = str(ran_code) # uuid类型转为字符串类型
ran_code = ran_code.replace('-', '') # 将中间的-去掉
print("替换后:", ran_code)
request.session[ran_code] = user.id
message = '''
亲爱的用户:
您好!此链接用于【用户找回密码】,请点击链接:<a href = 'http:
如果链接不能点击,请复制以下链接在浏览器中打开即可:
http:
Mikasa个人博客团队
''' % (ran_code, ran_code)
# 发送邮件
result = send_mail(subject, message, EMAIL_HOST_USER, [email, ])
return result
4、forms.py
- 因为我们这里引用到了captcha图片验证码,如下是captcha表单的使用方法

class CaptchaTestForm(forms.Form):
"""
验证码captcha的Form
"""
# email = EmailField(required=True, error_messages={'required': "必须填写邮箱"}, label="邮箱")
captcha = CaptchaField()
四、templates模块具体实现
- 页面这part包括之前的【登录注册】页面我也进行了一点小优化
1、新增forget_pwd.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
忘记密码
{% endblock %}
{# css样式部分 #}
{% block mycss %}
<link href="{% static 'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
<link href="
600,600i,700,700i,800,800i" rel="stylesheet"/>
{% endblock %}
{# 内容部分 #}
{% block content %}
<div class="main">
<div class="main-w31">
<h1 class="logo-w3">忘记密码</h1>
<div class="w3layouts-main">
<p style="color: #d01b1b">{{ msg }}{{ errors }}</p>
<form action="{% url 'user:forget_pwd' %}" method="post"> {% csrf_token %}
<input placeholder="请输入邮箱地址" name="email" type="email" required="">
{# 图片验证码 #}
{{ form.captcha }}
<br><br>
<input type="submit" value="找回密码" name="login">
</form>
<br><br>
<a href="{% url 'user:login' %}"><span>已有账号,去登录</span></a>
<a href="{% url 'user:register' %}"><span>注册新用户?</span></a>
</div>
</div>
</div>
{% endblock %}
{# js 部分#}
{% block myjs %}
<script>
$(function () {
{# 可以直接去浏览器上面查找元素定位 #}
$('.captcha').click(function () {
var img = $(this);
$.getJSON('/captcha/refresh', function (data) {
console.log(data)
img.attr('src', data['image_url'])
$('#id_captcha_0').val(data['key'])
})
});
$('#id_captcha_1').blur(function () {
const $this = $(this);
const key = $('#id_captcha_0').val();
const code = $(this).val();
$.getJSON('{% url 'user:valid_code' %}', {key: key, code: code}, function (data) {
console.log(data)
$('#result').remove();
if (data.status == 1) {
$this.after('<span id="result">验证码正确</span>')
} else {
$this.after('<span id="result" style="color: #d01b1b">验证码错误,请重新输入</span>')
}
})
})
})
</script>
{% endblock %}
2、新增update_pwd.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
更新密码
{% endblock %}
{# css样式部分 #}
{% block mycss %}
<link href="{% static 'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
<link href="
600,600i,700,700i,800,800i" rel="stylesheet"/>
{% endblock %}
{# 内容部分 #}
{% block content %}
<div class="main">
<div class="main-w31">
<h1 class="logo-w3">更新密码</h1>
<div class="w3layouts-main">
<p style="color: #ffffff">{{ msg }}{{ errors }}</p>
<form action="{% url 'user:update_pwd' %}" method="post"> {% csrf_token %}
{# 拿到返回的唯一标识码,即意味着你要更新密码的用户是哪个 #}
<input type="hidden" value="{{ c }}" name="code">
<input placeholder="请输入新密码" name="password" type="password" required="">
<input placeholder="请再次确认密码" name="repassword" type="password" required="">
<input type="submit" value="更新密码">
</form>
</div>
</div>
</div>
{% endblock %}
3、login.html优化

<br><br>
<a href="{% url 'user:forget_pwd' %}"><span>忘记密码?</span></a>
<a href="{% url 'user:register' %}"><span>注册新用户</span></a>
4、register.html优化

<br><br>
<a href="{% url 'user:forget_pwd' %}"><span>忘记密码?</span></a>
<a href="{% url 'user:login' %}"><span>已有账号,去登录</span></a>
五、项目启动及查看


|