0%

Register SMS and Email Confirmation

用户注册 - Django 后端

短信验证码,邮件验证链接

源码来自:《Python Django Web 典型模块开发实战》
整理:CK

短信认证

1. 发送短信的模块 - 应该任何api key都能使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# utils/yunpian.py

import requests
class YunPian(object):
"""
应该任何api key都能使用
云片地址固定
"""

def __init__(self,api_key):
self.api_key=api_key
self.single_send_url='https://sms.yunpian.com/v2/sms/single_send.json'
def send_sms(self,code,mobile):
parmas={
'apikey':self.api_key,
'mobile':mobile,
'text':'您的验证码是{code}。如非本人操作,请忽略本短信。'.format(code=code)
}
#text 必须和短信后台模版一致否则无法发送
r=requests.post(self.single_send_url,data=parmas)
print(r)
if __name__=='__main__':
yun_pian=YunPian('***************(你的API key)')
yun_pian.send_sms('***(验证码)','*******(手机号)')

2. 验证码 - 跟短信服务商无关,又后端生成和管理,校验

1
2
3
4
5
6
7
8
9
10
11
12
13
class Code(models.Model):
"""
验证码
"""
phone=models.CharField(max_length=11,verbose_name='手机号')
code=models.CharField(max_length=4,verbose_name='验证码')
add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')
end_time = models.DateTimeField(default=datetime.now, verbose_name='过期时间')
class Meta:
verbose_name='验证码表'
verbose_name_plural = verbose_name
def __str__(self):
return self.phone

3. 发送验证码 - 检查手机号是否合法,等待x秒后才能重发

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
from django.shortcuts import render,HttpResponse
import json
import re
import datetime
import random
from demo4.settings import APIKEY
#引入用户表和验证码表
from .models import Code,UserProfile
#引入对接云片网模块
from utils.yunpian import YunPian
#引入drf功能模块
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
class SendCodeView(APIView):
"""
获取手机验证码
"""
def get(self,request):
phone=request.GET.get('phone')
if phone:
#验证是否为有效手机号
mobile_pat = re.compile('^(13\d|14[5|7]|15\d|166|17\d|18\d)\d{8}$')
res = re.search(mobile_pat, phone)
if res:
#如果手机号合法,查看手机号是否被注册过
had_register=UserProfile.objects.filter(phone=phone)
if had_register:
msg = '手机号已被注册!'
result = {"status": "402", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
else:
#检测是否发送过,如果没发送过则发送验证码,如果发送过则另做处理
had_send=Code.objects.filter(phone=phone).last()
if had_send:
#如果这个号码发送过验证码,查看距离上次发送时间间隔有没有达到一分钟
if had_send.add_time.replace(tzinfo=None)>(datetime.datetime.now()-datetime.timedelta(minutes=1)):
msg = '距离上次发送验证码不足1分钟!'
result = {"status": "403", "data": {'msg': msg}}
return HttpResponse(json.dumps(result,ensure_ascii=False), content_type="application/json,charset=utf-8")
else:
# 发送验证码
code = Code()
code.phone = phone
# 生成验证码
c = random.randint(1000, 9999)
code.code = str(c)
# 设定验证码的过期时间为20分钟以后
code.end_time = datetime.datetime.now() + datetime.timedelta(minutes=20)
code.save()
# 调用发送模块
code = Code.objects.filter(phone=phone).last().code
yunpian = YunPian(APIKEY)
sms_status = yunpian.send_sms(code=code, mobile=phone)
msg = sms_status
return HttpResponse(msg)
else:
#发送验证码
code = Code()
code.phone = phone
#生成验证码
c = random.randint(1000, 9999)
code.code = str(c)
#设定验证码的过期时间为20分钟以后
code.end_time=datetime.datetime.now()+datetime.timedelta(minutes=20)
code.save()
#调用发送模块
code = Code.objects.filter(phone=phone).last().code
yunpian = YunPian(APIKEY)
sms_status = yunpian.send_sms(code=code, mobile=phone)
msg = sms_status
# print(msg)
return HttpResponse(msg)
else:
msg = '手机号不合法!'
result = {"status": "403", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),content_type="application/json,charset=utf-8")
else:
msg = '手机号为空!'
result = {"status": "404", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),content_type="application/json,charset=utf-8")

4. 验证 - 用户填写的验证码是否正确,过期

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
class RegisterView(APIView):
"""
注册类
"""
def get(self,request):
username=request.GET.get('username')
pwd=request.GET.get('pwd')
phone=request.GET.get('phone')
email=request.GET.get('email')
code=request.GET.get('code')
if username:
pass
else:
msg = '用户名不能为空!'
result = {"status": "404", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
if pwd:
pass
else:
msg = '密码不能为空!'
result = {"status": "404", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
if phone:
pass
else:
msg = '手机号不能为空!'
result = {"status": "404", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
if email:
pass
else:
msg = '邮箱不能为空!'
result = {"status": "404", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
if code:
pass
else:
msg = '验证码不能为空!'
result = {"status": "404", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
#查找对比验证码
code1=Code.objects.filter(phone=phone).last()
if code==code1:
#验证验证码是否已经过期
end_time=code1.end_time
end_time=end_time.replace(tzinfo=None)
if end_time > datetime.datetime.now():
user = UserProfile()
user.username = username
user.password = pwd
user.phone = phone
user.email=email
user.save()
msg = '注册成功!'
result = {"status": "200", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
else:
msg = '验证码已过期!'
result = {"status": "403", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")
else:
msg = '验证码错误!'
result = {"status": "403", "data": {'msg': msg}}
return HttpResponse(json.dumps(result, ensure_ascii=False),
content_type="application/json,charset=utf-8")

邮件验证

邮件发送激活链接