当前位置:   article > 正文

Python项目实战 3.2:验证码.短信验证码_python怎么调用发短信验证码的逻辑

python怎么调用发短信验证码的逻辑

目录

一、短信验证码逻辑分析

二、关于短信平台:

三、短信验证码后端逻辑

四、短信验证码前端逻辑


一、短信验证码逻辑分析

要点

1. 保存短信验证码是为注册做准备的。

2. 为避免用户使用图形验证码恶意测试,后端提取了图形验证码后,立即删除图形验证码。

3. Django不具备发送短信的功能,所以我们借助第三方的短信平台来帮助我们发送短信验证码。

二、关于短信平台:

Python对接 阿里云短信平台_mengnf的专栏-CSDN博客

三、短信验证码后端逻辑

3.1 短信验证码接口设计

1. 请求方式

选项方案
请求方法GET
请求地址/sms_codes/(?P<mobile>1[3-9]\d{9})/

2. 请求参数:路径参数和查询字符串

参数名类型是否必传说明
mobilestring手机号
image_codestring图形验证码
uuidstring唯一编号

3. 响应结果:JSON

字段说明
code状态码
errmsg错误信息

3.2 短信验证码接口定义(verifications\views.py

  1. class SMSCodeView(View):
  2. """短信验证码"""
  3. def get(self, request, mobile):
  4. """
  5. :param mobile: 手机号
  6. :return: JSON
  7. """
  8. # 接受参数
  9. image_code_client = request.GET.get('image_code')
  10. uuid = request.GET.get('uuid')
  11. # 校验参数
  12. if not all([image_code_client, uuid]):
  13. return http.HttpResponseForbidden('缺少必传参数')
  14. # 创建连接到redis的对象
  15. redis_conn = get_redis_connection('verify_code')
  16. # 判断用户是否频繁发送短信验证码
  17. send_flag = redis_conn.get('send_flag_%s' % mobile)
  18. if send_flag:
  19. return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '发送短信过于频繁'})
  20. # 提取图形验证码
  21. image_code_server = redis_conn.get('img_%s' % uuid)
  22. if image_code_server is None:
  23. return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码已失效'})
  24. # 删除图形验证码
  25. redis_conn.delete('img_%s' % uuid)
  26. # 对比图形验证码
  27. image_code_server = image_code_server.decode() # 将bytes转字符串,再比较
  28. if image_code_client.lower() != image_code_server.lower(): # 转小写,再比较
  29. return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '输入图形验证码有误'})
  30. # 生成短信验证码:随机6位数字,000007
  31. sms_code = '%06d' % random.randint(0, 999999)
  32. logger.info(sms_code) # 手动的输出日志,记录短信验证码
  33. # # 保存短信验证码
  34. # redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
  35. # # 保存发送短信验证码的标记
  36. # redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
  37. # 创建redis管道
  38. pl = redis_conn.pipeline()
  39. # 将命令添加到队列中
  40. # 保存短信验证码
  41. pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
  42. # 保存发送短信验证码的标记
  43. pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
  44. # 执行
  45. pl.execute()
  46. # 发送短信验证码
  47. 这里调用发送短信的方法如:阿里云api.send(参数,,,)
  48. # 响应结果
  49. return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '发送短信成功'})

四、短信验证码前端逻辑

4.1 Vue绑定短信验证码界面

1.register.html

  1. <li>
  2. <label>短信验证码:</label>
  3. <input type="text" v-model="sms_code" @blur="check_sms_code" name="sms_code" id="msg_code" class="msg_input">
  4. <a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]</a>
  5. <span class="error_tip" v-show="error_sms_code">[[ error_sms_code_message ]]</span>
  6. {% if sms_code_errmsg %}
  7. <span class="error_tip">{{ sms_code_errmsg }}</span>
  8. {% endif %}
  9. </li>

2.register.js

  1. check_sms_code(){
  2. if(this.sms_code.length != 6){
  3. this.error_sms_code_message = '请填写短信验证码';
  4. this.error_sms_code = true;
  5. } else {
  6. this.error_sms_code = false;
  7. }
  8. },

4.2 axios请求短信验证码

1.发送短信验证码事件处理

  1. // 发送短信验证码
  2. send_sms_code() {
  3. // 避免恶意用户频繁的点击获取短信验证码的标签
  4. if (this.send_flag == true) { // 先判断是否有人正在上厕所
  5. return; // 有人正在上厕所,退回去
  6. }
  7. this.send_flag = true; // 如果可以进入到厕所,立即关门
  8. // 校验数据:mobile,image_code
  9. this.check_mobile();
  10. this.check_image_code();
  11. if (this.error_mobile == true || this.error_image_code == true) {
  12. this.send_flag = false;
  13. return;
  14. }
  15. let url = '/sms_codes/' + this.mobile + '/?image_code=' + this.image_code + '&uuid=' + this.uuid;
  16. axios.get(url, {
  17. responseType: 'json'
  18. })
  19. .then(response => {
  20. if (response.data.code == '0') {
  21. // 展示倒计时60秒效果
  22. let num = 60;
  23. let t = setInterval(() => {
  24. if (num == 1) { // 倒计时即将结束
  25. clearInterval(t); // 停止回调函数的执行
  26. this.sms_code_tip = '获取短信验证码'; // 还原sms_code_tip的提示文字
  27. this.generate_image_code(); // 重新生成图形验证码
  28. this.send_flag = false;
  29. } else { // 正在倒计时
  30. num -= 1; // num = num - 1;
  31. this.sms_code_tip = num + '秒';
  32. }
  33. }, 1000)
  34. } else {
  35. if (response.data.code == '4001') { // 图形验证码错误
  36. this.error_image_code_message = response.data.errmsg;
  37. this.error_image_code = true;
  38. } else { // 4002 短信验证码错误
  39. this.error_sms_code_message = response.data.errmsg;
  40. this.error_sms_code = true;
  41. }
  42. this.send_flag = false;
  43. }
  44. })
  45. .catch(error => {
  46. console.log(error.response);
  47. this.send_flag = false;
  48. })
  49. },




register.js完整代码:

  1. // 我们采用的时ES6的语法
  2. // 创建Vue对象 vm
  3. let vm = new Vue({
  4. el: '#app', // 通过ID选择器找到绑定的HTML内容
  5. // 修改Vue读取变量的语法
  6. delimiters: ['[[', ']]'],
  7. data: { // 数据对象
  8. // v-model
  9. username: '',
  10. password: '',
  11. password2: '',
  12. mobile: '',
  13. allow: '',
  14. image_code_url: '',
  15. uuid: '',
  16. image_code: '',
  17. sms_code_tip: '获取短信验证码',
  18. send_flag: false, // 类比上厕所,send_flag就是锁,false表示门开,true表示门关
  19. sms_code: '',
  20. // v-show
  21. error_name: false,
  22. error_password: false,
  23. error_password2: false,
  24. error_mobile: false,
  25. error_allow: false,
  26. error_image_code: false,
  27. error_sms_code: false,
  28. // error_message
  29. error_name_message: '',
  30. error_mobile_message: '',
  31. error_image_code_message: '',
  32. error_sms_code_message: '',
  33. },
  34. mounted() { // 页面加载完会被调用的
  35. // 生成图形验证码
  36. this.generate_image_code();
  37. },
  38. methods: { // 定义和实现事件方法
  39. // 发送短信验证码
  40. send_sms_code() {
  41. // 避免恶意用户频繁的点击获取短信验证码的标签
  42. if (this.send_flag == true) { // 先判断是否有人正在上厕所
  43. return; // 有人正在上厕所,退回去
  44. }
  45. this.send_flag = true; // 如果可以进入到厕所,立即关门
  46. // 校验数据:mobile,image_code
  47. this.check_mobile();
  48. this.check_image_code();
  49. if (this.error_mobile == true || this.error_image_code == true) {
  50. this.send_flag = false;
  51. return;
  52. }
  53. let url = '/sms_codes/' + this.mobile + '/?image_code=' + this.image_code + '&uuid=' + this.uuid;
  54. axios.get(url, {
  55. responseType: 'json'
  56. })
  57. .then(response => {
  58. if (response.data.code == '0') {
  59. // 展示倒计时60秒效果
  60. let num = 60;
  61. let t = setInterval(() => {
  62. if (num == 1) { // 倒计时即将结束
  63. clearInterval(t); // 停止回调函数的执行
  64. this.sms_code_tip = '获取短信验证码'; // 还原sms_code_tip的提示文字
  65. this.generate_image_code(); // 重新生成图形验证码
  66. this.send_flag = false;
  67. } else { // 正在倒计时
  68. num -= 1; // num = num - 1;
  69. this.sms_code_tip = num + '秒';
  70. }
  71. }, 1000)
  72. } else {
  73. if (response.data.code == '4001') { // 图形验证码错误
  74. this.error_image_code_message = response.data.errmsg;
  75. this.error_image_code = true;
  76. } else { // 4002 短信验证码错误
  77. this.error_sms_code_message = response.data.errmsg;
  78. this.error_sms_code = true;
  79. }
  80. this.send_flag = false;
  81. }
  82. })
  83. .catch(error => {
  84. console.log(error.response);
  85. this.send_flag = false;
  86. })
  87. },
  88. // 生成图形验证码的方法:封装的思想,代码复用
  89. generate_image_code() {
  90. this.uuid = generateUUID();
  91. this.image_code_url = '/image_codes/' + this.uuid + '/';
  92. },
  93. // 校验用户名
  94. check_username() {
  95. // 用户名是5-20个字符,[a-zA-Z0-9_-]
  96. // 定义正则
  97. let re = /^[a-zA-Z0-9_-]{5,20}$/;
  98. // 使用正则匹配用户名数据
  99. if (re.test(this.username)) {
  100. // 匹配成功,不展示错误提示信息
  101. this.error_name = false;
  102. } else {
  103. // 匹配失败,展示错误提示信息
  104. this.error_name_message = '请输入5-20个字符的用户名';
  105. this.error_name = true;
  106. }
  107. // 判断用户名是否重复注册
  108. if (this.error_name == false) { // 只有当用户输入的用户名满足条件时才回去判断
  109. let url = '/usernames/' + this.username + '/count/';
  110. axios.get(url, {
  111. responseType: 'json'
  112. })
  113. .then(response => {
  114. if (response.data.count == 1) {
  115. // 用户名已存在
  116. this.error_name_message = '用户名已存在';
  117. this.error_name = true;
  118. } else {
  119. // 用户名不存在
  120. this.error_name = false;
  121. }
  122. })
  123. .catch(error => {
  124. console.log(error.response);
  125. })
  126. }
  127. },
  128. // 校验密码
  129. check_password() {
  130. let re = /^[0-9A-Za-z]{8,20}$/;
  131. if (re.test(this.password)) {
  132. this.error_password = false;
  133. } else {
  134. this.error_password = true;
  135. }
  136. },
  137. // 校验确认密码
  138. check_password2() {
  139. if (this.password != this.password2) {
  140. this.error_password2 = true;
  141. } else {
  142. this.error_password2 = false;
  143. }
  144. },
  145. // 校验手机号
  146. check_mobile() {
  147. let re = /^1[3-9]\d{9}$/;
  148. if (re.test(this.mobile)) {
  149. this.error_mobile = false;
  150. } else {
  151. this.error_mobile_message = '您输入的手机号格式不正确';
  152. this.error_mobile = true;
  153. }
  154. // 判断手机号是否重复注册
  155. if (this.error_mobile == false) {
  156. let url = '/mobiles/' + this.mobile + '/count/';
  157. axios.get(url, {
  158. responseType: 'json'
  159. })
  160. .then(response => {
  161. if (response.data.count == 1) {
  162. this.error_mobile_message = '手机号已存在';
  163. this.error_mobile = true;
  164. } else {
  165. this.error_mobile = false;
  166. }
  167. })
  168. .catch(error => {
  169. console.log(error.response);
  170. })
  171. }
  172. },
  173. // 校验图形验证码吗
  174. check_image_code() {
  175. if (this.image_code.length != 4) {
  176. this.error_image_code_message = '请输入图形验证码';
  177. this.error_image_code = true;
  178. } else {
  179. this.error_image_code = false;
  180. }
  181. },
  182. // 校验短信验证码
  183. check_sms_code() {
  184. if (this.sms_code.length != 6) {
  185. this.error_sms_code_message = '请填写短信验证码';
  186. this.error_sms_code = true;
  187. } else {
  188. this.error_sms_code = false;
  189. }
  190. },
  191. // 校验是否勾选协议
  192. check_allow() {
  193. if (!this.allow) {
  194. this.error_allow = true;
  195. } else {
  196. this.error_allow = false;
  197. }
  198. },
  199. // 监听表单提交事件
  200. on_submit() {
  201. this.check_username();
  202. this.check_password();
  203. this.check_password2();
  204. this.check_mobile();
  205. this.check_sms_code();
  206. this.check_allow();
  207. // 在校验之后,注册数据中,只要有错误,就禁用掉表单的提交事件
  208. if (this.error_name == true || this.error_password == true || this.error_password2 == true || this.error_mobile == true || this.error_sms_code == true || this.error_allow == true) {
  209. // 禁用掉表单的提交事件
  210. window.event.returnValue = false;
  211. }
  212. },
  213. }
  214. });

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/744599
推荐阅读
相关标签
  

闽ICP备14008679号