• 极光发送短信验证码


    注意:个人无法使用此功能,因为个人申请使用是不会通过的

    流程介绍

    创建过程详细浏览一遍,文档介绍的很详细
    之后调用API需要用到的参数有:
    APP KEY、MASTER SECRET
    极光短信签名ID、极光验证码短信ID(这俩都是创建短信模板的时候生成的)
    极光短信开发文档
    在这里插入图片描述
    短信签名解释
    在这里插入图片描述
    创建过程
    在这里插入图片描述

    本文实现了发送文本验证码短信 、验证码验证
    下面是需要用到的API

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    注意:
    这里发生HTTP请求调用,需要采用 HTTP 基本认证的验证方式 做法为,HTTP Header 中加 Authorization: Header 名称是 "Authorization", 值是 base64 转换过的 "appKey:masterSecret"(中间有个冒号)。这两者可以在极光开发者服务的 Web 控制台[应用设置]-[应用信息]中查看。

    在这里插入图片描述

    代码实现

    这里使用hutool工具包发送http请求
    hutool发送Http请求-HttpRequest
    使用 hutool 工具包发送 HTTP 请求
    依赖:

    		<!--Hutool-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.7.16</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    yaml配置

    #极光
    jiguang:
      jpush:
        #极光开发APP KEY
        app-key: ""
        #极光开发MASTER SECRET
        master-secret: ""
        #极光短信签名ID
        message-sign-id: ""
        #极光验证码短信ID
        captcha-template-id: ""
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    发送短信验证码:

    /**
         * 发送手机号验证码
         *
         * @param phoneNumber 解密后的手机号
         * @return 是否成功
         */
        @Override
        public CommonResult<Boolean> sendCaptcha(String phoneNumber) {
            //判断今天短信验证发送次数是否合规
            if (!captchaInfoService.isCaptchaRequestAvailable(phoneNumber)) {
                return new CommonResult<>(HttpCode.WRONG_PARAM, "今日发送数量过多", false);
            }
    
            //发送短信验证码
            String msgId = sendCaptchaNetworkHandler(phoneNumber);
            if (msgId != null) {
                //设置Redis中对于手机号和msgId的记录
                setRedisRecord(phoneNumber, msgId);
                return new CommonResult<>(HttpCode.SUCCESS, "发送成功", true);
            } else {
                return new CommonResult<>(HttpCode.INTERNAL_ERROR, "发送失败", false);
            }
    
        }
    
        /**
         * 发送手机号验证码
         * 参考文档:https://docs.jiguang.cn/jsms/server/rest_api_jsms#功能说明
         */
        private String sendCaptchaNetworkHandler(String phoneNumber) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("mobile", phoneNumber);
            jsonObject.put("sign_id", JPUSH_MESSAGE_SIGN_ID);
            jsonObject.put("temp_id", JPUSH_CAPTCHA_TEMPLATE_ID);
    
            //返回msg_id
            String result = HttpRequest.post("https://api.sms.jpush.cn/v1/codes")
                    .basicAuth(JPUSH_APP_KEY, JPUSH_MASTER_SECRET)
                    .body(jsonObject.toString())
                    .timeout(20000)
                    .execute().body();
    
            JSONObject resultJson = JSONObject.parseObject(result);
            if (resultJson.containsKey(MESSAGE_ID_KEY)) {
                return resultJson.getString(MESSAGE_ID_KEY);
            } else {
                return null;
            }
    
        }
    
    • 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

    短信验证码验证(极光提供了短信验证码验证功能,但是也可以再加一层redis验证,即发送验证码的时候就在redis中存储,登录时比对一下)

    /**
         * 获取对应手机号在Redis中的key
         * 举例:CAPTCHA:19825031998:VALUE
         *
         * @return 手机号在Redis中的key
         */
        String getRecordKey(String phone) {
            return CAPTCHA_RECORD_KEY_PREFIX + phone + CAPTCHA_RECORD_KEY_SUFFIX;
        }
    
        /**
         * 判断验证码和手机号是否匹配
         * 参考文档: https://docs.jiguang.cn/jsms/server/rest_api_jsms#请求示例-2
         *
         * 因为极光提供了验证码验证api
         * 所以可以不用再在redis中添加对应的phoneNumber和captcha对,
         * 当然也可以写入redis并设置过期时间
         *
         * 如果写入redis则当做判断时可以判断两次,
         * 1.调用极光验证码验证api
         * 2.自己redis中是否有对应的captcha
         *
         * @param captcha     验证码
         * @param phoneNumber 手机号
         * @return 是否正确
         */
        @Override
        public CommonResult<Boolean> checkCaptcha(int captcha, String phoneNumber) {
            //获取Key
            String recordKey = getRecordKey(phoneNumber);
            //查询手机号对应的验证码ID
            Object queryResult = redisTemplate.opsForValue().get(recordKey);
            //如果为空,说明没有记录,直接返回
            if (queryResult == null) {
                return new CommonResult<>(HttpCode.WRONG_PARAM, "无发送记录", null);
            }
            //获取msgId的值(注:msg_id 为调用发送验证码 API 的返回值)
            String msgId = String.valueOf(queryResult);
    
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", captcha);
    
            String result = HttpRequest.post("https://api.sms.jpush.cn/v1/codes/" + msgId + "/valid")
                    .basicAuth(JPUSH_APP_KEY, JPUSH_MASTER_SECRET)
                    .body(jsonObject.toString())
                    .timeout(20000)
                    .execute().body();
    
            JSONObject resultJson = JSONObject.parseObject(result);
    
            if (resultJson.containsKey(MESSAGE_IS_VALID_KEY)) {
                return new CommonResult<>(HttpCode.SUCCESS, "成功", resultJson.getBoolean(MESSAGE_IS_VALID_KEY));
            } else {
                return new CommonResult<>(HttpCode.INTERNAL_ERROR, "内部错误", null);
            }
    
        }
    
        @Override
        public Boolean isCaptchaRequestAvailable(String phoneNumber) {
            //获得每日发送的次数的Redis Key
            Object countQueryObject = redisTemplate.opsForHash().get(CAPTCHA_COUNT_MAP_KEY, phoneNumber);
    
            //如果是NULL,说明数据库里还没有这个数据,就允许发送
            if (countQueryObject == null) {
                return true;
            } else {
                //查询当前已经发送的次数
                int count = Integer.parseInt(String.valueOf(countQueryObject));
                //判断是否查出了最大次数
                return count <= CAPTCHA_MAX_REQUEST_PER_DAY;
            }
    
        }
    
    • 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

    完整代码参见:
    https://gitee.com/xunan29/sms-verification-redis

  • 相关阅读:
    JDK8新特性--函数式接口--(Consumer的概念理解,模拟练习,企业实战)全流程彻底搞懂
    Python 潮流周刊#24:no-GIL 提案正式被采纳了!
    SSM实战-复选框(checkbox)多标签分类的添加、标签回显与修改
    FPN模型
    [AIGC] Maven 简介: Java 项目构建的利器
    基于Java+MySQL+Tomcat+maven+JavaScript+Servlet的个人博客系统
    Kafka 消费者解析
    在线标定新思路!SST-Calib:最新Camera-Lidar时空同步标定算法(ITSC 2022)
    英语小三门
    Python 毕设精品实战案例——快速索引目录Part2
  • 原文地址:https://blog.csdn.net/munangs/article/details/126801411