Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 334|回复: 0

阿里云短信验证解决方案(java版)(redis存储)

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-13 13:09:27 | 显示全部楼层 |阅读模式

    最近搞了一个互联网项目的注册,需要写一个手机号验证(由于之前没有轮子,只能自己摸索了);

     

    1:基本思路:

    1>购买了阿里云短信服务->下载阿里云短信发送demo(java版);

    2>后端随机产生二维码,通过阿里云短信服务${code}进行发送

    3>同时记录发送的code和客户端的手机号,存储在redis中,redis过期时间60秒;

    4>用户注册提交将客户端手机号和验证码与redis中的key和value对比,存在则注册成功(同时删除redis对应缓存数据),不存在则返回;

    如需询问 可加我QQ820688215

    ========================================================================================================

    代码如下:

    redis工具代码

    maven:

    <!--阿里云短信服务-->
    <dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.0.6</version>
    </dependency>
    <dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>1.1.0</version>
    </dependency>
    <!--redis服务-->
    <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
    </dependency>


    redis 服务类
    public class RedisClientServer {
    
        private  static  final Logger logger = LoggerFactory.getLogger(RedisClientServer.class);
    
        private  static JedisPool jedisPool = null;
    
        private  static Jedis jedis = null;
    
        public  static Jedis jedis_object = null;
    
        private static String host = "127.0.0.1";
         private static String password = "123456";
        private static Integer port = 6379;
    
    
        static{
            if(jedisPool == null){
                JedisPoolConfig config = new JedisPoolConfig();
                //设置最大连接数
                config.setMaxTotal(500);
                //设置最大空闲数
                config.setMaxIdle(20);
                //设置最小空闲数
                config.setMinIdle(8);
                //设置超时时间
                config.setMaxWaitMillis(3000);
                //Idle时进行连接扫描
                config.setTestWhileIdle(true);
                //表示idle object evitor两次扫描之间要sleep的毫秒数
                config.setTimeBetweenEvictionRunsMillis(30000);
                //表示idle object evitor每次扫描的最多的对象数
                config.setNumTestsPerEvictionRun(10);
                //表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor
                //扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
                config.setMinEvictableIdleTimeMillis(60000);
                //初始化连接池
                jedisPool = new JedisPool(config, host, port);
                jedis_object = new   Jedis( host, port);
            }
        }
    
        private  RedisClientServer() {
    
        }
    
        private static Jedis  getJedisInstance(){
    
            try {
                if(null == jedis){
                    jedis = jedisPool.getResource();
                    jedis.auth(password);
                }
            } catch (Exception e) {
                logger.error("实例化jedis失败.........", e);
            }
            return jedis;
        }
    
        /**
         * 向缓存中设置字符串内容
         *@author liudianpeng.com
         *@date
         */
        public static boolean set(String key, String value) throws Exception {
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                jedis.set(key, value);
                return true;
            } catch (Exception e) {
                logger.error("redis set方法失败...key="+key+"  value="+value, e);
            } finally {
                jedisPool.close();
            }
            return false;
        }
    
        /**
         * 向缓存中设置字符串内容 ,设置过期时间
         *@author liudianpeng.com
         *@date
         */
        public static boolean set(String key, String value,Integer seconds) throws Exception {
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                jedis.set(key, value);
                jedis.expire(key, seconds);
                return true;
            } catch (Exception e) {
                logger.error("redis set方法失败...key="+key+"  value="+value, e);
            } finally {
                jedisPool.close();
            }
            return false;
        }
    
        /**
         * 根据key 获取内容
         *@author liudianpeng.com
         *@date
         */
        public static Object get(String key) {
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                Object value = jedis.get(key);
                return value;
            } catch (Exception e) {
                logger.error("redis get方法失败...key="+key);
            } finally {
                jedisPool.close();
            }
            return null;
        }
    
        /**
         * 删除缓存中得对象,根据key
         *@author liudianpeng.com
         *@date
         */
        public static boolean del(String key) {
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                jedis.del(key);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                jedisPool.close();
            }
            return false;
        }
    
        /**
         * 根据key 获取对象
         *@author liudianpeng.com
         *@date
         */
        public static <T> T get(String key, Class<T> clazz) {
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                String value = jedis.get(key);
                return JSON.parseObject(value, clazz);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                jedisPool.close();
            }
            return null;
        }
    
        /**
         *  设置key过期
         *@author
         *@date
         */
        public  static   boolean  expire(String key,int seconds){
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                jedis.expire(key, seconds);
                return  true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                jedisPool.close();
            }
            return false;
        }
    
        /**
         * 判断是否存在key
         *@author
         *@date
         */
        public static Boolean exists(String key){
            Jedis jedis = null;
            try {
                jedis = getJedisInstance();
                return jedis.exists(key);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }finally {
                jedisPool.close();
            }
        }
    
    }
    

     随机code生成工具

    public class CoreUtils {
        /**
         * 生成随机字符串
         *
         * @param length
         * @return
         */
        public static String randomString(int length, boolean isNumeric) {
            String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            if (isNumeric) {
                base = "0123456789";
            }
    
            Random random = new Random();
            StringBuffer buffer = new StringBuffer(length);
            for (int i = 0; i < length; i++) {
                buffer.append(base.charAt(random.nextInt(base.length())));
            }
    
            return buffer.toString();
        }
    
        /**
         * 不重复的参数进行拼装,返回查询条件字符串
         *
         * @param parameters 参数map
         * @param sort       是否按照字典排序
         * @return
         */
        public static String generateQueryString(Map<String, Object> parameters, boolean sort) {
            ArrayList<String> list = new ArrayList<String>();
            for (Map.Entry<String, Object> entry : parameters.entrySet()) {
                // log.debug("参数:{}", entry.getKey());
                if (!"".equals(entry.getValue())) {
                    list.add(entry.getKey() + "=" + entry.getValue());
                }
            }
    
            String[] arrayToSort = list.toArray(new String[list.size()]);
            if (sort) {
                Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
            }
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < list.size(); i++) {
                buffer.append(arrayToSort);
                if (i < (list.size() - 1)) {
                    buffer.append("&");
                }
            }
            return buffer.toString();
        }
    
        /**
         * 根据参数获得相关签名
         *
         * @param buffer  加密参数,ASCII 码从小到大排序(字典序)
         * @param encrypt 加密方式 SHA1 MD5
         * @return
         */
        public static String signature(String buffer, String encrypt, boolean toUpperCase) {
            String sign = "";
    
            if ("MD5".equals(encrypt)) {
                // MD5加密
                sign = Hashing.md5().hashString(buffer, Charsets.UTF_8).toString();
            } else if ("SHA1".equals(encrypt)) {
                // SHA1加密
                sign = Hashing.sha1().hashString(buffer, Charsets.UTF_8).toString();
            }
    
            if (toUpperCase) {
                sign = sign.toUpperCase();
            }
    
            return sign;
        }
    
        /**
         * 根据参数获得相关签名
         *
         * @param params  加密参数,ASCII 码从小到大排序(字典序)
         * @param encrypt 加密方式 SHA1 MD5
         * @return
         */
        public static String signature(Map params, String encrypt, boolean toUpperCase) {
            String sign = "";
            // 拼接字符串,按照字典排序
            String buffer = generateQueryString(params, true);
    
            // log.debug("待加密的字符串 => {}", buffer.toString());
            if ("MD5".equals(encrypt)) {
                // MD5加密
                sign = Hashing.md5().hashString(buffer, Charsets.UTF_8).toString();
            } else if ("SHA1".equals(encrypt)) {
                // SHA1加密
                sign = Hashing.sha1().hashString(buffer, Charsets.UTF_8).toString();
            }
            // log.debug("加密后的字符串 <=> {}", sign);
    
            if (toUpperCase) {
                sign = sign.toUpperCase();
            }
    
            return sign;
        }
    }
    

     

    阿里云短信服务配置

     

    /**
     * SmsDemo 是官方demo
     * 对其进行了修改,
     * 1:sendMsg 发送短信消息给客户端,需要客户端传入手机号
     */
    public class MessageUtils {
    
        /**
         * 发送短信消息方法,返回验证码
         * @param phone 用户手机号
         * @return true 发送成功 ;false 发送失败
         */
        public static Boolean sendMsg(String phone) throws Exception {
    
            //设置超时时间-可自行调整
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
            //初始化ascClient需要的几个参数
            final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
            final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
            //替换成你的AK
            final String accessKeyId = "";//你的accessKeyId,参考本文档步骤2
            final String accessKeySecret = "";//你的accessKeySecret,参考本文档步骤2
    
            //初始化ascClient,暂时不支持多region(请勿修改)
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
                    accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            //组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            //使用post提交
            request.setMethod(MethodType.POST);
            //必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
            request.setPhoneNumbers(phone);
            //必填:短信签名-可在短信控制台中找到
            request.setSignName("你的短信签名");
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode("SMS_0930219321");
            String checkCode = CoreUtils.randomString(6, true);//此处是生成6位数验证码工具类
            //request.setTemplateParam("{\"code\":\"123\"}");//测试用,此处json一定要严格按照json格式书写
            request.setTemplateParam("{\"code\":\""+checkCode+"\"}");
            //可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
            //request.setSmsUpExtendCode("90997");
            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
            request.setOutId("yourOutId");
            //请求失败这里会抛ClientException异常
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")){
                //请求成功,短信已发送
                //将手机号和生成的随机数存入redis 并设置redis的过期时间
                RedisClientServer.set(phone,checkCode,60);
            }
            return sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK");
        }
        //测试发送短信
        public static void main (String[] args) throws Exception {
    
            Boolean s = MessageUtils.sendMsg("13279879821");//手机号
            System.out.println("=========="+s);
        }
    

     

     

    //客户端请求处理

     

       //获取redis缓存中的手机号(key)和验证码(value):///////////////////////////
            if ("".equals((RedisClientServer.get(dto.getMobile())).toString())||
                    null==(RedisClientServer.get(dto.getMobile())).toString()){
                return Results.json().render("验证码已过期");
            }else {
                //删除缓存数据
                RedisClientServer.del(dto.getMobile());
            }
    

     

     

     

     

     



    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-2 07:00 , Processed in 0.063017 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表