随机生成验证码及发送短信验证码

验证码

包括过期时间和redis缓存以及校验

1.设置过期时间

private Date getNextDayZeroTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DAY_OF_MONTH, 1);
    calendar.set(Calendar.HOUR_OF_DAY, 2);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

2.随机生成验证码和验证码令牌

public String generateSmsCode() {
    Random random = new Random();
    String ch = "0123456789qwertyuiopasdfghjklzxcvbnm";
    int length = ch.length();
    String str = "";
    for (int i = 0; i < 6; i++) {
        int index = random.nextInt(length);
        str += ch.substring(index, index + 1);
    }
    return str;
}
public String verifyCode() {
    Random random = new Random();
    String ch = "0123456789";
    int length = ch.length();
    String str = "";
    for (int i = 0; i < 4; i++) {
        int index = random.nextInt(length);
        str += ch.substring(index, index + 1);
    }
    return str;
}

3.把验证码写入redis

public Tuple getCode(UserVo userVo) {
    CodeVo codeVo = new CodeVo();
    String validateNumber = "sms";
    RedisLock redisLock = new RedisLock(redisTemplate, validateNumber, 60000, 60000);
    String codeLimitKey = "key:phone:count:" + userVo.getTelPhone();
    String codeLimitValue = redisLock.get(codeLimitKey);
    Integer codeLimit = StringUtils.isBlank(codeLimitValue) ? 0 : Integer.parseInt(codeLimitValue);
    if (codeLimit.intValue() > 5) {
        return Tuple.createTuple(1, "验证码次数已达上限");
    }
    redisLock.set(codeLimitKey, codeLimit + 1 + "");
    //redisLock.setNX(codeLimitKey, codeLimit + 1 + "");
    redisLock.expireAt(codeLimitKey, this.getNextDayZeroTime());
    String verifyCode = this.verifyCode();
    String msgCode = this.generateSmsCode();
    codeVo.setSmsCode(msgCode);
    codeVo.setVerifyCode(verifyCode);
    codeVo.setTelPhone(userVo.getTelPhone());
    codeVo.setCodeNum(codeLimitValue);
    String codeVoStr = FastJsonUtil.beanToJson(codeVo);
    redisLock.setNX("key:phone:code:" + verifyCode, codeVoStr, 5 * 60);
    return Tuple.createTuple(0, codeVo);
}

4.实体类

public class CodeVo {
    private String verifyCode;//验证码令牌
    private String codeNum;//验证码次数
    private String smsCode;//短信验证码
    private String telPhone;//手机号码

5.redis方法

从redis取出来

public String get(final String key) {
   Object obj = null;
   try {
      obj = redisTemplate.execute(new RedisCallback<Object>() {
         @Override
         public Object doInRedis(RedisConnection connection) throws DataAccessException {
            RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
            byte[] data = connection.get(serializer.serialize(key));
            // connection.close();
            if (data == null) {
               return null;
            }
            return serializer.deserialize(data);
         }
      });
   } catch (Exception e) {
      logger.error("get redis error, key : {}", key);
      logger.error("error in RedisLock get :" + e.getMessage());
   }
   return obj != null ? obj.toString() : null;
}

存入redis

public void set(final String key, final String value) {
   redisTemplate.execute(new RedisCallback<Serializable>() {
      @Override
      public Serializable doInRedis(RedisConnection connection) throws DataAccessException {
         connection.set(redisTemplate.getStringSerializer().serialize(key), redisTemplate.getStringSerializer().serialize(value));
         return true;
      }
   });
}

设置过期时间

public Boolean expireAt(String key, Date date) {
   return redisTemplate.expireAt(key, date);
}

6.申请短信验证码账号

@Value("${message.url}")
	private String url;

	@Value("${message.appKey}")
	private String appKey;

	@Value("${message.appSecret}")
	private String appSecret;

	@Value("${message.localURL}")
	private String localURL;

	@Value("${message.name}")
	private String name;

	@Value("${message.pwd}")
	private String pwd;

7.发送短信验证码

package cn.zhaocha.message;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import cn.zhaocha.common.config.MessageConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class XiooMsgService {

	@Autowired
	private MessageConfig messageConfig;
	private static Logger log = LoggerFactory.getLogger(XiooMsgService.class);

	public enum MsgResultCode {
		SUCCUSS("0", "提交成功"), SENSITIVE("1", "含有敏感词汇"), NO_MONEY("2", "余额不足"), NO_PHONE("3", "没有号码"), BAD_SQL("4", "包含sql语句"), NO_ACCOUNT("10",
				"账号不存在"), ACCOUNT_DEAD("11", "账号注销"), ACCOUNT_STOP("12", "账号停用"), BAD_IP("13", "IP鉴权失败"), BAD_FORMAT("14", "格式错误"), SYSTEM_ERROR("-1", "系统异常");

		public static String codeOf(String paymentType) {
			for (MsgResultCode item : values()) {
				if (item.getCode().equals(paymentType)) {
					return item.getMsg();
				}
			}
			throw new RuntimeException("没有匹配的短信结果信息");
		}

		private String code;
		private String msg;

		public String getCode() {
			return code;
		}

		public String getMsg() {
			return msg;
		}

		MsgResultCode(String code, String msg) {
			this.code = code;
			this.msg = msg;
		}
	}

	public void sendSmsCode(String phone, String smsCode) {
		String content = new StringBuffer("您的验证码为" + smsCode + ",如非本人操作,请忽略本短信,本验证码有效时间5分钟。").toString();
		this.sendMsg(phone, content);
	}
	private void sendMsg(String phone, String msg) {
		if (StringUtils.isEmpty(phone) || !phone.startsWith("1")) {
			return;
		}
		String name = messageConfig.getName();
		String pwd = messageConfig.getPwd();
		StringBuffer mobileString = new StringBuffer(phone);
		String sign = "xx";
		String stime = "";
		StringBuffer extno = new StringBuffer();

		try {
			String resultStr = doPost(name, pwd, mobileString, msg, sign, stime, extno, messageConfig);
			log.info("短信 结果" + phone + "  " + resultStr);
			if (resultStr.contains(",")) {
				String result = resultStr.split(",")[0];
				log.info(result + "  " + MsgResultCode.codeOf(result));
			} else {
				log.info("短信 结果 没有逗号" + phone + "  " + resultStr);
			}
		} catch (Exception e) {
			log.info(e.toString());
		}
	}

	public static String doPost(String name, String pwd, StringBuffer mobileString, String contextString, String sign, String stime, StringBuffer extno,
			MessageConfig messageConfig) throws Exception {
		StringBuffer param = new StringBuffer();
		param.append("name=" + name);
		param.append("&pwd=" + pwd);
		param.append("&mobile=").append(mobileString);
		param.append("&content=").append(URLEncoder.encode(contextString.toString(), "UTF-8"));
		param.append("&stime=" + stime);
		param.append("&sign=").append(URLEncoder.encode(sign, "UTF-8"));
		param.append("&type=pt");
		param.append("&extno=").append(extno);

		// URL localURL = new URL("http://api.duanxin123.cn/asmx/smsservice.aspx?");
		URL localURL = new URL(messageConfig.getLocalURL());
		URLConnection connection = localURL.openConnection();
		HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

		httpURLConnection.setDoOutput(true);
		httpURLConnection.setRequestMethod("POST");
		httpURLConnection.setRequestProperty("Accept-Charset", "utf-8");
		httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		httpURLConnection.setRequestProperty("Content-Length", String.valueOf(param.length()));

		OutputStream outputStream = null;
		OutputStreamWriter outputStreamWriter = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		String resultBuffer = "";

		try {
			outputStream = httpURLConnection.getOutputStream();
			outputStreamWriter = new OutputStreamWriter(outputStream);

			outputStreamWriter.write(param.toString());
			outputStreamWriter.flush();

			if (httpURLConnection.getResponseCode() >= 300) {
				throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
			}

			inputStream = httpURLConnection.getInputStream();
			resultBuffer = convertStreamToString(inputStream);

		} finally {

			if (outputStreamWriter != null) {
				outputStreamWriter.close();
			}

			if (outputStream != null) {
				outputStream.close();
			}

			if (reader != null) {
				reader.close();
			}

			if (inputStreamReader != null) {
				inputStreamReader.close();
			}

			if (inputStream != null) {
				inputStream.close();
			}

		}

		return resultBuffer;
	}

	public static String convertStreamToString(InputStream is) {
		StringBuilder sb1 = new StringBuilder();
		byte[] bytes = new byte[4096];
		int size = 0;

		try {
			while ((size = is.read(bytes)) > 0) {
				String str = new String(bytes, 0, size, "UTF-8");
				sb1.append(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb1.toString();
	}

}

7.在生成验证码的地方调用发送短信验证码

8.校验

String validateNumber="sms";
RedisLock redisLock=new RedisLock(redisTemplate,validateNumber,60000,10000);
String codeKey=redisLock.get("key:phone:code:"+userVo.getVerifyCode());
CodeVo codeVo= FastJsonUtil.jsonToBean(codeKey, CodeVo.class);
System.out.println(codeVo.getSmsCode());
if (!codeVo.getSmsCode().equalsIgnoreCase(userVo.getCode())) {
   return Tuple.createTuple(1, "验证码错误");
}
发布了13 篇原创文章 · 获赞 3 · 访问量 648

猜你喜欢

转载自blog.csdn.net/weixin_45183530/article/details/94391402