阿里雲短信驗證解決方案(java版)(redis存儲)


最近搞了一個互聯網項目的注冊,需要寫一個手機號驗證(由於之前沒有輪子,只能自己摸索了);

 

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[i]);
            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());
        }

 

 

 

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM