背景:
最近和前端小伙伴一起搭建一个个人博客网站,注册功能为防止恶意破解密码、博客灌水等,在注册时做到手机号唯一且为本人手机号,故采用了阿里云的短信验证码(之前试过邮箱发送验证码,不知道为啥,经常被当垃圾邮件给拦截)
步骤:
- 登录阿里云,选择短信服务(可直接搜索短信服务)
- 点击开通短服务(点击免费开通 我这采用的是用多少给多少 并不是买套餐 感觉我的网站用户量达不到那么大)
3.进入快速学习模块,如果没有签名和模板请自行参照帮助文档提供的规范来申请,一般来说一两个小时就能审批下来
4.签名和模板都审批下来了,最重要的就是先往阿里云充点钱,不然用不了,别问我为什么,问马爸爸 噢 张爸爸去。。
5.鼠标移至右上角头像处,你会看见accesskeys,弹出安全提示,点击继续使用AccessKeys,创建你的accesskey,注意要记住自己的AccessKeyId和AccessKeySecret后面会有用到
6.好啦,阿里云上的部分就是这些,下面开始进入代码部分
首先引入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>
就这两个足矣
然后我们创建一个AliyunSmsUtils
package com.zty.blog.util;
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.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
/**
* @author zty
* 阿里云短信服务:
* 注意:需要 签名名称、模版CODE 以及 RAM访问控制中的 AccessKeyID 和 AccessKeySecret
* 如果是发送验证码 除了我标出的部分 无需修改其他的
*/
public class AliyunSmsUtils {
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi";
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com";
// TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
static final String accessKeyId = "输入自己的accesskeyId"; // TODO 修改成自己的
static final String accessKeySecret = "输入自己的accesskeySecret"; // TODO 修改成自己的
public static SendSmsResponse sendSms(String telephone, String code) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持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();
//必填:待发送手机号
request.setPhoneNumbers(telephone);
//必填:短信签名-可在短信控制台中找到
request.setSignName("修改为自己的签名"); // TODO 修改成自己的
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode("修改为自己的模板CODE"); // TODO 修改成自己的
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"123\"}");
request.setTemplateParam("{\"code\":\"" + code + "\"}");//如果为发送验证码 无需修改
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if(sendSmsResponse.getCode()!= null && sendSmsResponse.getCode().equals("OK")){
System.out.println("短信发送成功!");
}else {
System.out.println("短信发送失败!");
}
return sendSmsResponse;
}
}
接下来就是调用这个工具类发送短信了
验证码单独写一个工具类(用于生成一个五位数验证码)
package com.zty.blog.util;
import java.util.Random;
/**
* @author: zty
* @date 2019/10/5 下午2:33
* @description: 生成10000-99999的随机数
*/
public class RandomUtil {
public static int returnCode() {
Random rand = new Random();
return rand.nextInt(89999) + 10000;
}
}
短信的过期时间控制采用redis缓存来实现
获取验证码用Get请求就行了
如果用springsecurity 记得打开该接口的权限
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.zty.blog.dao.UserMapper;
import com.zty.blog.enums.ResultEnum;
import com.zty.blog.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import static com.zty.blog.util.AliyunSmsUtils.sendSms;
/**
* @author: zty
* @date 2019/10/6 下午1:33
* @description:
*/
@RestController
@Slf4j
@RequestMapping("/code")
@Api(tags = "验证码生成接口")
@CrossOrigin
public class SecurityCodeController {
@Autowired
private RedisUtil redisUtil;
@Autowired
private UserMapper userMapper;
@GetMapping("/getCode")
@ApiOperation("获取验证码")
public Object getCode(@RequestParam String username) throws ClientException {
boolean isHave = (userMapper.selectUserByUsername(username) != null);
if (isHave){
return ResultVOUtil.error(ResultEnum.USER_HAS_EXIST);
}if (redisUtil.get(username)!=null){
redisUtil.del(username);
}
String optCode = String.valueOf(RandomUtil.returnCode());
redisUtil.set(username, optCode, 300);
//这里由于没有用短信发送 为了获取验证码是多少 我们打印到控制台
SendSmsResponse response =sendSms(username,optCode); // TODO 填写你需要测试的手机号码
log.info("短信接口返回的数据----------------");
log.info("Code=" + response.getCode());
log.info("Message=" + response.getMessage());
log.info("RequestId=" + response.getRequestId());
log.info("BizId=" + response.getBizId());
return ResultVOUtil.success();
}
}
测试
在swagger中进行测试