验证码功能流程:
1前端页面点击《免费获取验证码》按钮,发送Ajax请求到后端
2后端接到请求后:
1)生成随机验证码
2)存储验证码
3)发送验证码
3前端注册时提交验证码,后端在注册逻辑中对比验证码是否正确
前端:
function regist() { <!--使用jquery拿数据--> var username = $('.username').val(); var email = $('.email').val(); var password1 = $('.password_1').val(); var password2 = $('.password_2').val(); var phone = $('.phone').val(); var sms_num = $('.sms_num').val(); <!--组织json对象--> var post_data = {"username":username, "email":email, "password1":password1, "password2":password2, "phone":phone,"sms_num":sms_num} <!--提交数据--> $.ajax({ type:"post", contentType:"application/json", dataType:"json", <!--把json对象转化成json字符串--> data:JSON.stringify(post_data), url:"http://127.0.0.1:8000/v1/users", success:function (result) { if (result.code == 200){ alert('注册成功') }else{ alert('注册失败') } } }) } function sendSMS() { var phone = $('.phone').val(); var post_data = {"phone":phone}; $.ajax({ type:"post", contentType: "application/json", dataType: "json", url:"http://127.0.0.1:8000/v1/users/sms/duanxin", data:JSON.stringify(post_data), success:function (result) { if (result.code == 200){ alert("短信发送成功") }else{ alert(result.error) } } }) } </script>
后端:
1在windows里安装redis并配置环境变量:
链接:https://pan.baidu.com/s/1DlgCMEfv97U9v8EV3KMZZA 提取码:abcd
2配置环境变量:
把安装目录D:\Program Files\Redis配置到windows环境变量里
3打开cmd窗口执行命令redis-cli进行测试
二在django的setting里配置redis缓存
1)安装django-redis库
pip install django-redis
2)在setting.py里配置缓存:
#django-redis配置(将django与redis融合) CACHES = { "default":{ "BACKEND": "django_redis.cache.RedisCache", #指定1库 "LOCATION": "redis:127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", #"PASSWORD":"123456" } } }
3在Djangoshell里进行测试方法1:
D:\PycharmProjects\linuxTangblog>python manage.py shell >>> from django.core.cache import cache >>> d = ['a','b','c'] >>> cache.set('testk',d,900) #把d存入缓存,失效时间900秒 True >>> cache.get('testk') ['a', 'b', 'c'] >>>
4在Djangoshell里进行测试方法2:
>>> from django_redis import get_redis_connection >>> r = get_redis_connection() >>> r Redis<ConnectionPool<Connection<host=None,port=6379,db=0>>> >>> r.set('k1','v1') True >>> r.get('k1') b'v1' >>>
5在cmd里测试:
D:\PycharmProjects\linuxTangblog>redis-cli 127.0.0.1:6379> keys * #查看所有的key 1) ":1:testk" 127.0.0.1:6379> ttl ":1:testk" #查看还有多久过期 (integer) 321 127.0.0.1:6379>
6在注册视图里引入发送短信的类,然后编写发送短信方法:
from django.core.cache import cache from tools.sms import Yuntongxin from django.conf import settings #短信 def sms_view(request): if request.method != 'POST': result = {'code':201,'error':'请求方式并非post'} return JsonResponse(result) #获取请求体 json_str = request.body #转换成字典 json_obj = json.loads(json_str) #获取手机号 phone = json_obj.get('phone') print(phone) #生成随机码 code = random.randint(1000,9999) print('phone',phone,'code',code) #存储随机码900秒过期(库django-redis)pip install django-redis cache_key = 'sms_%s'%(phone) cache.set(cache_key,code,900) #发送随机码 send_sms(phone,code) return JsonResponse({'code':200}) #发短信 def send_sms(phone,code): config = { "accountSid": settings.SMS_ACCOUNT_SID, "accountToken": settings.SMS_ACCOUNT_TOKEN, "appId": settings.SMS_APPID, "templateId": settings.SMS_TEMPLATEID, } yun = Yuntongxin(**config) res = yun.run(phone, code) return res
7完善注册视图逻辑添加演技验证码比对逻辑::
def post(self,request): sms_num = json_obj.get('sms_num') #从库里查注册时填写的code old_code = cache.get('sms_%s'%(phone)) if not old_code: result = {'code':'405','error':'验证码已过期'} return JsonResponse(result) #客户提交的code可库里的code进行比对 if int(sms_num) != old_code: result = {'code': '405', 'error': '验证码不匹配'} return JsonResponse(result)
8完整的用户注册视图代码如下:
import json,random,hashlib from django.core.cache import cache from django.http import JsonResponse from django.shortcuts import render from django.utils.decorators import method_decorator from django.views import View from .models import UserProfile from tools.logging_dec import logging_check from tools.sms import Yuntongxin from django.conf import settings # Create your views here. class UserViews(View): #获取个人信息 def get(self,request,username=None): if username: #/v1/users/zhangsan try: user = UserProfile.objects.get(username=username) except Exception as e: result = {'code':208, 'error':'用户名不存在'} return JsonResponse(result) result = {'code':200,'username':username, 'data':{'info':user.info,'sign':user.sign,'nickname':user.nickname,'avatar':str(user.avatar)}} return JsonResponse(result) #用户注册 def post(self,request): json_str = request.body #获取前端的json提交 json_obj = json.loads(json_str) #把json串转换成python的对象 username = json_obj.get('username') email = json_obj.get('email') password1 = json_obj.get('password1') password2 = json_obj.get('password2') phone = json_obj.get('phone') sms_num = json_obj.get('sms_num') #参数的基本检查 if password1 != password2: result = {'code':206,'error':'两次提交密码不一致'} #把json对象转换成json串返给浏览器 return JsonResponse(result) #1检查用户名是否可用 queryset_users = UserProfile.objects.filter(username=username) if queryset_users: result = {'code':207,'error':'用户名已存在'} return JsonResponse(result) #手机号不能重复 queryset_phone = UserProfile.objects.filter(phone=phone) if queryset_phone: result = {'code':210,'error':'手机号已存在'} return JsonResponse(result) #比对手机验证码 old_code = cache.get('sms_%s'%(phone)) print(old_code) if not old_code: result = {'code':'405','error':'验证码已过期'} return JsonResponse(result) print(sms_num) if int(sms_num) != old_code: result = {'code': '405', 'error': '验证码不匹配'} return JsonResponse(result) #给明文密码加密 hash_object = hashlib.md5() hash_object.update(password1.encode()) #md5要求字节串而password1是字符串,必须转换 pwd = hash_object.hexdigest() #已经设置默认值的字段,在创建订单时可以不写 UserProfile.objects.create(username=username,nickname=username,password=pwd,email=email,phone=phone) result = {'code':200,'username':username,'data':{}} return JsonResponse(result) #更新用户信息[昵称,签名,个人描述] @method_decorator(logging_check) def put(self,request,username=None): #获取所有数据 json_str = request.body #把json串转换成字典 json_obj = json.loads(json_str) # #取用户(一查) # try: # user = UserProfile.objects.get(username=username) # except Exception as e: # result = {'code':208,'error':'用户名不存在'} # return JsonResponse(result) user = request.myuser #修改数据(二改) user.sign = json_obj['sign'] user.info = json_obj['info'] user.nickname = json_obj['nickname'] #保存数据(三更新) user.save() return JsonResponse({'code':200}) #修改头像 @logging_check def users_views(request,username): if request.method != 'POST': result = {'code':201,'error':'请求方式并非post'} return JsonResponse(result) # try: # user = UserProfile.objects.get(username=username) # except Exception as e: # result = {'code':208, 'error':'用户名不存在'} # return JsonResponse(result) user = request.myuser avatar = request.FILES['avatar'] user.avatar = avatar user.save() return JsonResponse({'code':200}) #短信 def sms_view(request): if request.method != 'POST': result = {'code':201,'error':'请求方式并非post'} return JsonResponse(result) #获取请求体 json_str = request.body #转换成字典 json_obj = json.loads(json_str) #获取手机号 phone = json_obj.get('phone') print(phone) #生成随机码 code = random.randint(1000,9999) print('phone',phone,'code',code) #检查是否有发过并且未过期的验证码(安全防范) cache_key = 'sms_%s' % (phone) old_code = cache.get(cache_key) if old_code: return JsonResponse({'code':406,'error':'900秒内已经发送过验证码'}) # 存储随机码900秒过期(库django-redis)pip install django-redis cache.set(cache_key,code,900) #发送随机码 send_sms(phone,code) return JsonResponse({'code':200}) #发短信 def send_sms(phone,code): config = { "accountSid": settings.SMS_ACCOUNT_SID, "accountToken": settings.SMS_ACCOUNT_TOKEN, "appId": settings.SMS_APPID, "templateId": settings.SMS_TEMPLATEID, } yun = Yuntongxin(**config) res = yun.run(phone, code) return res