短信接口调用错误码可以参考官网地址:
https://help.aliyun.com/knowledge_detail/57717.html?spm=5176.13394938.0.0.39ab30bbJDgksU
1.获取手机号
/**
* 阿里发送短信验证码
*
* @param phone 手机号码
* @param type 验证码的模版类型
* @return
* @throws Exception
*/
@RequestMapping("sendvcode")
public ReturnData newsendvcode(HttpServletResponse response, @RequestParam String phone, @RequestParam(value = "tpye", defaultValue = "3") Integer type) throws Exception {
try {
if (StringUtils.isBlank(phone)) {
return ReturnData.fail("缺少参数");
}
if (!CommonUtils.pattern(phone, RegexConstant.PHONE)) {//验证手机格式
return ReturnData.fail("手机号格式错误");
}
return userService.sendvcode(phone, type);
} catch (Exception e) {
logger.error("阿里发送短信错误", e);
return ReturnData.fail();
}
}
2.将接受的发送成功后写入缓存
@Override
public ReturnData sendvcode(String phone, Integer type) throws IOException, ClientException {
String vcode = CommonUtils.getRandomVcode(); //获取随机6位验证码
String templateParam = "{\"" + TemplateCodeConstant.CODE_TEMPLATECODE + "\":\"" + vcode + "\"}";
ReturnData returnData = SendMessager.sendMessage(phone, type, templateParam);
if (returnData.getErrcode() == 0) {
redisService.set(RedisCache.K_USER_PHONE, phone, vcode, (long) 60, TimeUnit.SECONDS);//用户的验证码
redisService.set(RedisCache.K_USER_TIME, "time" + phone, String.valueOf(System.currentTimeMillis()), (long) 3600, TimeUnit.SECONDS);//用户的时间
}
return returnData;
}
获取随机6位验证码
/**
* 获取随机6位验证码
*
* @return
*/
public static String getRandomVcode() {
Random random = new Random();
String result = "";
for (int i = 0; i < 6; i++) {
result += random.nextInt(10);
}
return result;
}
阿里发送短信
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.mmkj.registrationSystem.config.SpringContextUtils;
import com.mmkj.registrationSystem.dao.codeConfig.TemplateCodeConfigMapper;
import com.mmkj.registrationSystem.model.codeConfig.TemplateCodeConfig;
import com.mmkj.registrationSystem.service.config.RedisService;
import com.mmkj.registrationSystem.service.impl.config.RedisServiceImpl;
import com.mmkj.registrationSystem.util.redis.RedisCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Content:
*
* @auther: wha
* @Date: 2019/11/7 10:27
*/
public class SendMessager {
private static Logger logger= LoggerFactory.getLogger(SendMessager.class);
private static RedisService redisService = SpringContextUtils.getBean(RedisServiceImpl.class);//RedisService bean注入
private static TemplateCodeConfigMapper codeConfigMapper = SpringContextUtils.getBean(TemplateCodeConfigMapper.class);//TemplateCodeConfigMapper bean注入
private static TemplateCodeConfig getTemplateCodeConfig(Integer id) {
TemplateCodeConfig templateCodeConfig = codeConfigMapper.selectByPrimaryKey(id);
return templateCodeConfig;
}
/**
* @param phone 将要发送的短信手机号
* @param type 模版idsendMessage 1:注册,2:登录,3:身份验证
* @return
* @throws IOException
* @throws ClientException
*/
public static ReturnData sendMessage(String phone, Integer type,String templateParam) throws IOException, ClientException {
TemplateCodeConfig templateCodeConfig = getTemplateCodeConfig(type);
//设置超时时间——可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", templateCodeConfig.getConnectTime().toString());
System.setProperty("sun.net.client.defaultReadTimeout", templateCodeConfig.getReadTime().toString());
// 初始化ascClient需要的几个参数
final String product = templateCodeConfig.getProduct().toString();// 短信API产品名称(短信产品名固定,无需修改)
final String domain = templateCodeConfig.getDomain().toString();// 短信API产品域名(接口地址固定,无需修改)
// 替换成你的AK
final String accessKeyId = templateCodeConfig.getAccessKeyId().toString();// 你的accessKeyId,参考本文档步骤2
final String accessKeySecret = templateCodeConfig.getAccessKeySecret().toString();// 你的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(templateCodeConfig.getSignName().toString());
// 必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCodeConfig.getTemplateCode().toString());
// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.setTemplateParam(templateParam);
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
return ReturnData.success();
} else {
logger.error("阿里云发送短信失败",sendSmsResponse);
return ReturnData.fail("阿里云发送短信失败");
}
}
/**
* 验证码校验
*/
public static ReturnData checkSmsMsg(String telnum, String code) {
String timeLong = redisService.get(RedisCache.K_USER_TIME, "time" + telnum).toString();
String vcode = (String) redisService.get(RedisCache.K_USER_PHONE, telnum);
if (CommonUtils.isEmptyString(vcode) || timeLong == null) {
return ReturnData.fail("验证码错误");
}
if (System.currentTimeMillis() - Long.parseLong(timeLong) > 5 * 60 * 1000) {
return ReturnData.fail("验证码超时");
}
if (!code.equals(vcode)) {
return ReturnData.fail("验证码错误");
}
return ReturnData.success();
}
}
验证码登录Controller
@RequestMapping("login")
public ReturnData userRegisterLogin(@RequestParam String phone, @RequestParam String vcode) throws Exception {
if (CommonUtils.isEmptyAllString(phone, vcode)) {
return ReturnData.fail("缺少参数");
}
if (!CommonUtils.pattern(phone, RegexConstant.PHONE)) {
return ReturnData.fail("手机号格式错误");
}
return userService.login(phone, vcode);
}
@Override
public ReturnData login(HttpServletRequest request, String phone, String vcode) {
ReturnData returnData = SendMessager.checkSmsMsg(phone, vcode);//验证码校验
if (returnData.getErrcode() == 0) {
// 校验手机号
User user = userMapper.selectUserByPhone(phone);
if(null != user){
return returnData.success(user);
}
}
return returnData.fail();
}