SpringBoot 實現手機短信驗證碼


下面是我具體實現的

<!-- 阿里雲OSS -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>2.8.3</version>
        </dependency>

 

/**
 * Created by mhSui on 2019/12/05.
 *
 * @author mhSui
 */
@Slf4j
@Configuration
public class SmsUtil {

	@Value("${aliyun.accessKeyId}")
	private String accessKeyId;

	@Value("${aliyun.secret}")
	private String secret;

	@Value("${aliyun.signName}")
	private String signName;

	@Value("${aliyun.templateCode}")
	private String templateCode;

	@Value("${aliyun.paramName}")
	private String paramName;

	@Autowired
	private RedisClient redisClient;

	/**
	 * 發送短信.
	 * @param mobile 手機號
	 * @return String
	 */
	@SuppressWarnings("deprecated")
	public String sendSms(String mobile) {
		// 檢驗手機號碼
		boolean isPhone = isPhone(mobile);
		if (!isPhone) {
			return ProcessEnum.PHONE_FORMAT_ERROR;
		}
		// 校驗是否重復發送
		String code = this.redisClient.get(mobile);
		if (code != null) {
			return ProcessEnum.SMS_FREQUENTLY;
		}

		String kaptcha = this.getKaptcha();
		Map<String, String> map = new HashMap<>(1);
		map.put(this.paramName, kaptcha);
		String templateParam = JSON.toJSONString(map);

		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
				this.accessKeyId, this.secret);
		IAcsClient client = new DefaultAcsClient(profile);

		CommonRequest request = new CommonRequest();
		request.setMethod(MethodType.POST);
		request.setDomain("dysmsapi.aliyuncs.com");
		request.setVersion("2017-05-25");
		request.setAction("SendSms");
		request.putQueryParameter("RegionId", "cn-hangzhou");
		request.putQueryParameter("PhoneNumbers", mobile);
		request.putQueryParameter("SignName", this.signName);
		request.putQueryParameter("TemplateCode", this.templateCode);
		request.putQueryParameter("TemplateParam", templateParam);

		try {
			CommonResponse response = client.getCommonResponse(request);
			String responseMessage = JSONObject.parseObject(response.getData())
					.getString("Message");

			if (!"ok".equals(responseMessage)) {
				// 短信發送成功,將驗證碼存儲到redis,並設置過期時間為5分鍾
				this.redisClient.set(mobile, kaptcha);
				this.redisClient.expire(mobile, 15 * 60);
				return ProcessEnum.SUCCESS;
			}

		}
		catch (ClientException e) {
			// 短信發送失敗
			return ProcessEnum.SMS_FAILED;
		}
		// 短信發送失敗
		return ProcessEnum.SMS_FAILED;

	}

	/**
	 * 中國電信號段 133、149、153、173、177、180、181、189、199. 中國聯通號段
	 * 130、131、132、145、155、156、166、175、176、185、186. 中國移動號段
	 * 134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188、198.
	 * 其他號段. 14號段以前為上網卡專屬號段,如中國聯通的是145,中國移動的是147等等. 虛擬運營商. 電信:1700、1701、1702.
	 * 移動:1703、1705、1706. 聯通:1704、1707、1708、1709、171. 衛星通信:1349.
	 * @param phone phone
	 * @return boolean
	 */
	public static boolean isPhone(String phone) {
		String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
		if (phone.length() != 11) {
			log.info("手機號應為11位數");
			return false;
		}
		else {
			Pattern p = Pattern.compile(regex);
			Matcher m = p.matcher(phone);
			boolean isMatch = m.matches();
			if (!isMatch) {
				log.info("手機號格式不正確");
			}
			return isMatch;
		}
	}

	/**
	 * 校驗短信驗證碼.
	 * @param mobile mobile
	 * @param kaptcha kaptcha
	 * @return 校驗結果
	 */
	public Boolean checkKaptcha(String mobile, String kaptcha) {
		String s = this.redisClient.get(mobile);
		return s != null && s.equals(kaptcha);
	}

	/**
	 * 生成短信驗證碼並存儲.
	 * @return kaptcha
	 */
	private String getKaptcha() {
		StringBuilder str = new StringBuilder();
		Random random = new Random();

		for (int i = 0; i < 4; i++) {
			// 生成一個[0,10)
			int randomInt = random.nextInt(10);
			str.append(randomInt);
		}
		return str.toString();
	}

}

  


免責聲明!

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



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