因为我们短信验证码生命周期控制的非常严格!而且数据用完后不需要存储. 所以建议直接把数据存储在缓存/内存中!
pip install django-redis
配置Redis为Django的缓存,替换原来的session
#配置Redis为Django缓存
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/0", #地址
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
# 将session缓存在Redis中
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
# session 设置(可以不写)
SESSION_COOKIE_AGE = 60 * 60 * 12 # 12小时
SESSION_SAVE_EVERY_REQUEST = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 关闭浏览器,则COOKIE失效
from django.core.cache import cache
def test_redis(request):
# 存储数据
chache.set("name", "tom", 20) # 该值的有效期为20s
# 判断Redis中是否存在
print(cache.has_kay("name")) # 包含: true
# 获取
print(cache.get("name")) # 返回: tom 无返回null
return HttpResponse("测试Redis")
参考文档 申请阿里云短信服务.pdf文档
#!/usr/bin/env python
#coding=utf-8
import random
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
from utils import restful
def send_sms(phone,code):
client = AcsClient('mxTYXZ4QDQecJQDN', 'znxNezmm4zfA9kPyqx1WrpznjCaJFT', 'cnhangzhou')
#phone = '17600950805'
#aa= '222222'
code = "{'code':%s}"%(code)
request = CommonRequest()
request.set_accept_format('json')
request.set_domain('dysmsapi.aliyuncs.com')
request.set_method('POST')
request.set_protocol_type('https') # https | http
request.set_version('2017-05-25')
request.set_action_name('SendSms')
request.add_query_param('RegionId', 'cn-hangzhou')
request.add_query_param('PhoneNumbers', phone)
request.add_query_param('SignName', '北网')
request.add_query_param('TemplateCode', 'SMS_162738723')
request.add_query_param('TemplateParam',code )
response = client.do_action(request)
# python2: print(response)
print(str(response, encoding = 'utf-8'))
return str(response, encoding = 'utf-8')
#数字表示生成几位, True表示生成带有字母的 False不带字母的
def get_code(n=6,alpha=True):
s = '' # 创建字符串变量,存储生成的验证码
for i in range(n): # 通过for循环控制验证码位数
num = random.randint(0,9) # 生成随机数字0-9
if alpha: # 需要字母验证码,不用传参,如果不需要字母的,关键字alpha=False
upper_alpha = chr(random.randint(65,90))
lower_alpha = chr(random.randint(97,122))
num = random.choice([num,upper_alpha,lower_alpha])
s = s + str(num)
return s
if __name__ == '__main__':
send_sms('18434288349', get_code(6,False))
print(get_code(6,False)) # 打印6位数字验证码
print(get_code(6,True)) # 打印6位数字字母混合验证码
print(get_code(4,False)) # 打印4位数字验证码
print(get_code(4,True)) # 打印4位数字字母混合验证码
流程:
获取手机号---->生成6位验证码–>缓存验证码到Redis—>发短信–>返回状态
# 发短信接口
def sms_send(request):
# http://localhost:8000/duanxin/duanxin/sms_send/?phone=18434288349
# 1 获取手机号
phone = request.GET.get('phone')
# 2 生成6位验证码
code = aliyunsms.get_code(6, False)
# 3 缓存到Redis
cache.set(phone,code,60) #60s有效期
print('判断缓存中是否有:',cache.has_key(phone))
print('获取Redis验证码:',cache.get(phone))
# 4 发短信
result = aliyunsms.send_sms(phone, code)
return HttpResponse(result)
流程:
获取前台电话和验证码----> 获取Redis中存的验证码—>对比是否相等–>返回结果
# 短信验证码校验
def sms_check(request):
# /duanxin/sms_check/?phone=xxx&code=xxx
# 1. 电话和手动输入的验证码
phone = request.GET.get('phone')
code = request.GET.get('code')
# 2. 获取redis中保存的code
print('缓存中是否包含:',cache.has_key(phone))
print('取值:',cache.get(phone))
cache_code = cache.get(phone)
# 3. 判断
if code == cache_code:
return HttpResponse(json.dumps({'result':'OK'}))
else:
return HttpResponse(json.dumps({'result':'False'}))
手动在浏览器上给假设的参数进行测试:
http://localhost:8000/duanxin/sms_send/?phone=手机号
http://localhost:8000/duanxin/sms_check/?phone=手机号&code=验证码
独立restful.py 接口模块!
参考:
https://blog.csdn.net/xyy1028/article/details/84981627
https://www.runoob.com/w3cnote/restful-architecture.html
统一的接口模块restful.py
#encoding: utf-8
from django.http import JsonResponse
class HttpCode(object):
ok = 200
pageerror = 404
methoderror = 405
servererror = 500
# {"code":400,"message":"","data":{}}
def result(code=HttpCode.ok,message="",data=None,kwargs=None):
json_dict = {"code":code,"message":message,"result":data}
if kwargs and isinstance(kwargs,dict) and kwargs.keys():
json_dict.update(kwargs)
return JsonResponse(json_dict,json_dumps_params={'ensure_ascii': False})
def ok(message='OK',data=None):
return result(code=HttpCode.ok,message=message,data=data)
def page_error(message="",data=None):
return result(code=HttpCode.pageerror,message=message,data=data)
def method_error(message='',data=None):
return result(code=HttpCode.methoderror,message=message,data=data)
def server_error(message='',data=None):
return result(code=HttpCode.servererror,message=message,data=data)
任何接口的返回结果,都是用resutful.py方法进行规整
# 短信验证码校验
def sms_check(request):
# /duanxin/sms_check/?phone=xxx&code=xxx
# 1. 电话和手动输入的验证码
phone = request.GET.get('phone')
code = request.GET.get('code')
# 2. 获取redis中保存的code
print('缓存中是否包含:',cache.has_key(phone))
print('取值:',cache.get(phone))
cache_code = cache.get(phone)
# 3. 判断
if code == cache_code:
#格式统一调整后的
return restful.ok("OK",data=None)
else:
#格式统一调整后的
return restful.params_error("验证码错误", data=None)