zoukankan      html  css  js  c++  java
  • 短信验证码的设计与实现

    准备:
      1.容联云通信注册账号并下载设置

      2.将yuntongxun文件夹复制到项目目录下

    短信验证码业务分析: 需要使用redis数据库 配置文件里添加如下设置

    CACHES = {
        "default": { # 默认的缓存配置
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/0",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
        # 我的需求是希望将session存储在redis的1号库
        "session": { # session后端
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
        "verify_code": { # 验证码
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/2",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
    }

    短信验证码后端接口设计:

    1.请求方式
    选项    方案
    请求方法    GET
    请求地址    /sms_codes/(?P<mobile>1[3-9]d{9})/
    请求参数:路径参数和查询字符串传参
    其中:mobile 是用路径传递参数的, image_code 和 image_code_id 是用查询字符串传递的参数.
    
    2.参数名    类型    是否必传    说明
    mobile    string    是      手机号
    image_code    string   是    图形验证码
    image_code_id    string   是    唯一编号
    
    3.响应结果:JSON
    字段    说明
    code    状态码
    errmsg    错误信息

     短信验证码实现 在视图集文件里添加代码

    class SMSCodeView(View):
    
        def get(self, reqeust, mobile):
            # 避免频繁发送短信验证码
            redis_conn = get_redis_connection('verify_code')
    
            send_flag = redis_conn.get('send_flag_%s' % mobile)
            if send_flag:
                return http.JsonResponse({'code': 400,
                                          'errmsg': '发送短信过于频繁'})
         
            image_code_client = reqeust.GET.get('image_code')
            uuid = reqeust.GET.get('image_code_id')
    
            if not all([image_code_client, uuid]):
                return http.JsonResponse({'code': 400,
                                          'errmsg': '缺少必传参数'})
    
            image_code_server = redis_conn.get('img_%s' % uuid)
            if image_code_server is None:
                return http.JsonResponse({'code': 400,
                                          'errmsg': '图形验证码失效'})
            try:
                redis_conn.delete('img_%s' % uuid)
            except Exception as e:
                logger.error(e)
    
            image_code_server = image_code_server.decode()
            if image_code_client.lower() != image_code_server.lower():
                return http.JsonResponse({'code': 400,
                                          'errmsg': '输入图形验证码有误'})
    
            sms_code = '%06d' % random.randint(0, 999999)
            logger.info(sms_code)
    
            # 创建管道对象: 
            pl = redis_conn.pipeline()
    
            # redis_conn.setex('sms_%s' % mobile, 300, sms_code)
            pl.setex('sms_%s' % mobile, 300, sms_code)
    
            # redis_conn.setex('send_flag_%s' % mobile, 60, 1)
            pl.setex('send_flag_%s' % mobile, 60, 1)
    
            # 执行管道: 
            pl.execute()
    
            CCP().send_template_sms(mobile, [sms_code, 5], 1)
    
            return http.JsonResponse({'code': 0,
                                      'errmsg': '发送短信成功'})

    配置短信验证码的url  

    urlpatterns = [
        re_path(r"^sms_codes/(?P<mobile>1[3-9]d{9})/$", views.SMSCodeView.as_view()), 
    ]

    短信验证码后端常见优化:

    1. 如何避免频繁发送短信验证码:
      在后端也要限制用户请求短信验证码的频率.
      60秒内只允许一次请求短信验证码.
      在 Redis 数据库中缓存一个数值,有效期设置为60秒.
    
    2. Redis服务端问题:
      如果Redis服务端需要同时处理多个请求,加上网络延迟,
      那么服务端利用率不高,效率降低。
      解决方案:pipeline
      1. 创建redis请求管道
      2. 将操作redis的多个命令请求添加到管道队列里
      3. 执行命令
    
    3.发送短信是耗时操作,如果短信被阻塞,用户响应会延迟,影响用户界面倒计时延迟
      """
      CCP().send_template_sms(mobile, [sms_code, 5], 1)
      return http.JsonResponse({'code': 0, 'errmsg': '发送短信成功'})
      """
      解决方案:异步方案redis 和 Celey
      异步发送短信
      将发送短信业务和响应分开执行,将发送短信 从主业务中 解耦出来
  • 相关阅读:
    前端--页面提交重置功能
    ztree获取当前选中节点子节点id集合的方法(转载)
    sqlserver锁表、解锁、查看销表 (转载)
    解决前端文件修改后浏览器页面未更新的问题
    简单的上传文件
    如何在Eclipse中查看JDK以及JAVA框架的源码(转载)
    设计模式--观察者模式
    WebService 学习
    学习quartz定时
    JS 中AJAX,Fetch,Axios关系
  • 原文地址:https://www.cnblogs.com/yqyn-study/p/13409541.html
Copyright © 2011-2022 走看看