1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 191.基于Django框架发送邮件与手机验证码详解

191.基于Django框架发送邮件与手机验证码详解

时间:2019-12-26 12:36:19

相关推荐

191.基于Django框架发送邮件与手机验证码详解

1.邮箱验证环境搭建

基本的项目搭建方式还是可以参考专栏中前几篇文章

model

创建模型,并迁移数据库(sqlite)

from django.db import models# Create your models here.class User(models.Model):username = models.CharField(max_length=30)password = models.CharField(max_length=100)

templates

在子应用下创建templates/code_app/register.html

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>用户注册</title></head><body><form action="" method="post">{% csrf_token %}<table><tr><td>用户名:</td><td><input type="text" id="username" name="username" placeholder="请输入您的邮箱号"></td></tr><tr><td>验证码:</td><td><input type="text" name="vcode" placeholder="请输入您的邮箱验证码"></td></tr><tr><td>密码:</td><td><input type="password" name="password" placeholder="请输入您的密码"></td></tr><tr><td>密码确认:</td><td><input type="password" name="password2" placeholder="请确认您的密码"></td></tr><tr><td colspan="2"><input type="submit" value="注册"></td></tr></table></form></body></html>

views

from django.shortcuts import render# Create your views here.def register_html(request):return render(request,'code_app/register.html')

urls

from django.contrib import adminfrom django.urls import path, includefrom code_app import viewsapp_name = 'code_app'urlpatterns = [path('register_html/',views.register_html)]

2. 邮箱验证smtp发送邮件

在根目录下创建common文件夹

生成随机码

创建string_help.py

import randomdef gen_vcode(length=4):# 返回一个随机字符串,生成4位验证码return ''.join(random.choices('0123456789', k=length))

发送邮件

创建mail_helper.py

from string_help import gen_vcodefrom email.header import Headerfrom email.mime.text import MIMETextfrom email.utils import parseaddr,formataddrimport smtplib# 格式化编码,以防乱码def _format_addr(s):name, addr = parseaddr(s)return formataddr((Header(name, 'utf-8').encode(), addr))# 构建发送邮件对象def gen_vcode_msg(vcode, from_addr, to_addr):"""vcode: 发送的验证码from_addr: 发送方邮箱to_addr: 接收方邮箱return: 返回含有发送验证码的MIMEText对象"""text = f'您好,欢迎注册测试网。您的验证码是:{vcode},有效期为20分钟, 请立即验证。'msg = MIMEText(text,'plain', 'utf-8')msg['From'] = _format_addr('测试网<%s>' %from_addr)msg['To'] = _format_addr('新用户<%s>' % to_addr)msg['Subject'] = Header('测试网注册验证码','utf-8').encode()return msgdef send_vcode(smtp_server, from_addr,password, to_addr):"""smtp_server: 当前使用smtp(qq邮箱)服务器from_addr: 发送方邮箱password: 发送方邮箱密码(授权码)to_addr: 接收方邮箱"""# 构建一个 smtp 对象server = smtplib.SMTP(smtp_server, 25)# 设置一个调试级别(上线可以关闭)server.set_debuglevel(1)# 登录server.login(from_addr, password)# 构造要发送邮件的内容vcode = gen_vcode() # 验证码msg = gen_vcode_msg(vcode, from_addr, to_addr) # 邮件对象# 发送邮件server.sendmail(from_addr, [to_addr],msg.as_string()) server.quit() # 退出return vcodeif __name__ == '__main__':from_addr = '1339559006@'to_addr = '1339559006@'password = 'bqruoshflxyijabe'smtp_server = ''code = send_vcode(smtp_server,from_addr, password, to_addr)print('发送的验证码:',code)

3.在模板中添加发送邮件

创建文件夹存放jquery

views

调用发送邮件函数(在第二点中)

from django.shortcuts import renderfrom common import mail_help,string_helpfrom django.conf import settingsfrom django.http import JsonResponse# Create your views here.def register_html(request):return render(request,'code_app/register.html')# 发送验证码def send_mail_vcode(request):username = request.POST.get('username')code = mail_help.send_vcode(settings.MAIL_SMTP_SERVER, settings.MAIL_FROM_ADDR,settings.MAIL_PASSWORD, username)resp = {'msg':'验证码已发送,请查阅'}return JsonResponse(resp)

修改templates

使用jquery调用视图函数,绑定到发送邮件按钮中

{% load static %}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>用户注册</title><script src="{% static 'code_app/js/jquery-3.6.1.min.js' %}"></script><!-- <script src="code_app\static\code_app\js\jquery-3.6.1.min.js"></script> --><script>// 由于django会进行csrf验证,如果不添加这个代码,那么所有的ajax的post请求,都会验证失败$.ajaxSetup({data: {csrfmiddlewaretoken: '{{ scrf_token }}' },});function send_mail_vcode() {// 获取用户邮箱var username = $('#username').val()// 提交ajax的请求$.ajax({url:"{% url 'code_app:send_mail_vcode' %}",type:'POST',data: {'username': username},success:function(data){alert(data['msg']);}})}</script></head><body><form action="" method="post">{% csrf_token %}<table><tr><td>用户名:</td><td><input type="text" id="username" name="username" placeholder="请输入您的邮箱号"></td></tr><tr><td>验证码:</td><td><input type="text" name="vcode" placeholder="请输入您的邮箱验证码"><input type="button" value="发送验证码" onclick="return send_mail_vcode();"></td></tr><tr><td>密码:</td><td><input type="password" name="password" placeholder="请输入您的密码"></td></tr><tr><td>密码确认:</td><td><input type="password" name="password2" placeholder="请确认您的密码"></td></tr><tr><td colspan="2"><input type="submit" value="注册"></td></tr></table></form></body></html>

配置settings

注释csrf中间件,否则报错Forbidden (CSRF token missing or incorrect.)

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','monMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',]

添加配置

STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]# Default primary key field type# /en/3.2/ref/settings/#default-auto-fieldDEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'# 邮箱配置MAIL_FROM_ADDR = '1339559006@'MAIL_PASSWORD = 'bqruoshflxyijabe'MAIL_SMTP_SERVER = ''

4. 邮箱验证验证码输入是否正确

4.1 邮箱验证验证码之保存验证码在session

可以保存验证码在session中,也可以参考专栏的Tornado项目,保存在redis中。

完善views代码

# 发送验证码def send_mail_vcode(request):username = request.POST.get('username')# 获取当前时间now_time = time.time()# 获取上次发送邮件的时间mail_code_time = request.session.get('mail_code_time')if mail_code_time and now_time < mail_code_time + settings.MAIL_INTERVAL:resp = {'msg':f'{settings.MAIL_INTERVAL}秒内,不能重复发送邮件'}else:code = mail_help.send_vcode(settings.MAIL_SMTP_SERVER, settings.MAIL_FROM_ADDR,settings.MAIL_PASSWORD, username)resp = {'msg':'验证码已发送,请查阅'}# 存储验证码request.session['mail_code'] = coderequest.session['mail'] = username# 存储发送邮件时间request.session['mail_code_time'] = time.time()return JsonResponse(resp)

settings配置

# 邮箱配置MAIL_INTERVAL = 20 # 不可以重复发送的时间

4.2 邮箱验证验证码之验证验证码是否正确

views视图函数

def validate_mail_vcode(request):# 获取输入的验证码和邮箱username = request.POST.get('username')vcode = request.POST.get('vcode')# 从session中获取邮箱和验证码session_username = request.session.get('mail')session_code = request.session.get('mail_code')# 判断发送用户是否一致if session_username and session_username == username:# 判断验证码是否失效now_time = time.time()# 获取发送验证码时间session_code_time = request.session.get('mail_code_time')if session_code_time and now_time <= session_code_time + settings.VCODE_EXPIRE:# 验证验证码输入if session_code and session_code == vcode:resp = {'ok':1,'msg':'验证码正确'}else:resp = {'ok':0,'msg':'验证码输入不正确'}else:resp = {'ok':0,'msg':'验证码失效,请重新获取'}else:resp = {'ok':0,'msg':'该账户没有获取验证码'}return JsonResponse(resp)

templates

{% load static %}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>用户注册</title><script src="{% static 'code_app/js/jquery-3.6.1.min.js' %}"></script><!-- <script src="code_app\static\code_app\js\jquery-3.6.1.min.js"></script> --><script>// 由于django会进行csrf验证,如果不添加这个代码,那么所有的ajax的post请求,都会验证失败$.ajaxSetup({data: {csrfmiddlewaretoken: '{{ scrf_token }}' },});function send_mail_vcode() {// 获取用户邮箱var username = $('#username').val()// 提交ajax的请求$.ajax({url:"{% url 'code_app:send_mail_vcode' %}",type:'POST',data: {'username': username},success:function(data){alert(data['msg']);}})}// 验证输入验证码是否正确function validate_vcode(){// 获取输入的邮箱var username = $('#username').val();// 在验证码输入框中添加id获取值var vcode = $('#vcode').val();// 发送异步请求进行验证$.ajax({// 调用视图函数url:"{%url 'code_app:validate_mail_vcode'%}",// 请求方式type:'POST',// 传递的数据data:{'vcode':vcode,'username':username},success:function(data){if(!data['ok']){alert(data['msg']);return false;}else{alert(data['msg']);return true;}}});// 若无获取到邮箱和验证码输入框存在内容return false;}</script></head><body><form action="" method="post" onsubmit="validate_vcode();">{% csrf_token %}<table><tr><td>用户名:</td><td><input type="text" id="username" name="username" placeholder="请输入您的邮箱号"></td></tr><tr><td>验证码:</td><td><input type="text" id='vcode' name="vcode" placeholder="请输入您的邮箱验证码"><input type="button" value="发送验证码" onclick="return send_mail_vcode();"></td></tr><tr><td>密码:</td><td><input type="password" name="password" placeholder="请输入您的密码"></td></tr><tr><td>密码确认:</td><td><input type="password" name="password2" placeholder="请确认您的密码"></td></tr><tr><td colspan="2"><input type="submit" value="注册"></td></tr></table></form></body></html>

settings配置

VCODE_EXPIRE = 60*2 # 验证码有效时间

效果展示

5. 邮箱验证通过完成注册

templates完善注册请求

views视图函数

from django.shortcuts import renderfrom common import mail_help,string_helpfrom django.conf import settingsfrom django.http import JsonResponse,HttpResponseimport timefrom code_app.models import *def register(request):# 获取表单中的数据username = request.POST.get('username')password = request.POST.get('password')# 添加到数据库user = User.objects.create(username = username,password = password)return HttpResponse(f'注册成功,{user.id}')

效果展示

6.短信验证

这里的短信验证将会和邮箱验证放在一起,可以按需获取代码

6.1 使用云片网发送短信验证

云片网网址:/注册账号新账户赠送0.5元,可以不用充值测试接入短信进行个人实名认证实名信息审核通过后,设置签名 和 短信模板需要获取两个信息: apikey短信模板 实现接口,查看api文档,选择使用单条发送接口 /official/document/sms/zh_CN/domestic_single_send

在common下创建yunpian.py发送短信请求

import jsonimport randomfrom urllib import parse, requestdef send_sms_single(apikey, text, mobile):"""通用接口发短信apikey:云片网的apikeytext:短信发送内容mobile:接收方手机号return :json_data"""url = '/v2/sms/single_send.json'headers = {"Content-type": "application/x-www-form-urlencoded;charset=utf-8;","Accept":"application/json;charset=utf-8;"}data = {'apikey': apikey,'text': text,'mobile': mobile}# apikey= &text= &mobile=data = parse.urlencode(data).encode('utf-8')# 生成有个request对象req = request.Request(url,headers=headers, data=data)# 执行发送 返回字符串content = request.urlopen(req).read().decode()# 将字符串转化成jsonjson_data = json.loads(content)return json_datadef send_sms(apikey, template, mobile):'''发送短信apikey:云片网账号 apikeytemplate: 云片网审核通过的模板内容mobile:接收方手机号return: True,vcode 是否发送成功,验证码'''# 生成随机验证码vcode = ''.join(random.choices('0123456789', k=4))# 生成短信内容text = template.format(vcode)# 调用发送短信方法json_data = send_sms_single(apikey, text, mobile)print('云片网结果:', json_data)if json_data['code'] == 0:return True, vcodeelse:return False, vcodeif __name__ == '__main__':apikey = 'b35ccda2ee775c10'template = '【一天拓客】您的验证码是{}。如非本人操作,请忽略本短信。'b, vcode = send_sms(apikey, template, '181')print(vcode)

6.2在模板中实验短信验证

settings

# 配置发送短信YUNPIAN_APIKEY = '5c10'YUNPIAN_TEMPLATE = '【一天拓客】您的验证码是{}。如非本人操作,请忽略本短信。' # 规定的模板

views视图

from django.shortcuts import renderfrom common import mail_help,string_help, yunpianfrom django.conf import settingsfrom django.http import JsonResponse,HttpResponseimport timefrom code_app.models import *# Create your views here.def register_html(request):return render(request,'code_app/register.html')# 发送验证码def send_vcode(request):username = request.POST.get('username')# 获取当前时间now_time = time.time()# 获取上次发送邮件的时间mail_code_time = request.session.get('mail_code_time')if mail_code_time and now_time < mail_code_time + settings.MAIL_INTERVAL:resp = {'msg':f'{settings.MAIL_INTERVAL}秒内,不能重复发送验证码'}else:# 判断输入的是邮箱还是手机号typ = string_help.mail_or_phone(username)if typ == string_help.MAIL:code = mail_help.send_vcode(settings.MAIL_SMTP_SERVER, settings.MAIL_FROM_ADDR,settings.MAIL_PASSWORD, username)resp = {'msg':'验证码已发送,请查阅'}elif typ == string_help.PHONE:# 发送短信验证flag, code = yunpian.send_sms(settings.YUNPIAN_APIKEY, settings.YUNPIAN_TEMPLATE, username)if not flag:resp = {'msg':'发送短信失败,请联系管理员'}else:resp = {'msg':'验证码已经发送,请查看手机'}else:resp = {'msg':'账号不合法,既不是邮箱也不是手机号'}# 存储验证码request.session['mail_code'] = coderequest.session['mail'] = username# 存储发送邮件时间request.session['mail_code_time'] = time.time()return JsonResponse(resp)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。