700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 阿里云接口实现发送短信验证码

阿里云接口实现发送短信验证码

时间:2018-06-24 09:14:02

相关推荐

阿里云接口实现发送短信验证码

java 阿里云接口实现发送短信验证码

1. 阿里云后台配置短信相关1.1 开通短信服务1.2 添加模板签名1.3 创建秘钥1.4 短信需要后台授权--注意点2 java--简单实现短信验证码发送2.1 引入pom依赖2.2 application.yml配置阿里AK2.3 编写阿里配置文件实体类2.4 编写阿里工具类2.5 编写短信缓存2.6 编写发送短信随机码--6位数2.7 发送短信接口2.8 校验验证码有没有过期2.9 判断手机号是否为空,手机格式是否有误2.10 验证成功后,移除缓存中的手机号验证码3 修改短信接口3.1 添加短信类型3.2 获取配置文件中短信时间跟最大次数3.3 对特别类型下进行校验3.4 动态设置失效时间3.5 规定时间内没有失效的校验3.6新建表,保存短信日志,3.8 结果图4 注意点4.1 模板签名正确性4.2 授权问题4.3 尽量把次数,失效时间,AK写到配置文件,方便修改4.4 谢谢点赞 ~^o^~

前言–很久没更新过东西了,突然想起来短信,回顾了一下之前的小项目,把阿里短信的内容简要讲述一下.

1. 阿里云后台配置短信相关

1.1 开通短信服务

打开官网,直接搜索短信服务,点击短信控制台进入开通短信服务。

阿里短信服务:/product/sms

1.2 添加模板签名

开通之后,配置模板及签名,可根据自己需求配置,审核时间官方给得:

一般模板预计2小时内审核完成,审核通过后可使用。工作时间:9:00-23:00 (法定节日顺延),建议您尽量在18:00前提交申请。

1.3 创建秘钥

AccessKey ID:***************

AccessKey Secret:**********

(建议保存好,很关键得一个AK,具有该账户完全的权限)

1.4 短信需要后台授权–注意点

(之前遇到得一个问题)没授权报错,发送失败

2 java–简单实现短信验证码发送

2.1 引入pom依赖

阿里短信服务文档、sdk下载/product/44282.html如果不是maven项目直接下载两个jar导入。

以下是maven

<!-- 阿里云短信 --><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.1.0</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>1.1.0</version></dependency>

2.2 application.yml配置阿里AK

ali:#阿里AK 换成自己的accessKeyId: ************************accessKeySecret: *******************#短信每天发送最大次数sendMaxTime: 10#短信失效时间 例如2分钟= 60*1000*2 =120000codeFailureTime: 120000

2.3 编写阿里配置文件实体类

package mon.utils.wx;import org.springframework.boot.context.properties.ConfigurationProperties;import org.ponent;@Component@ConfigurationProperties(prefix = "ali")public class AliConfig {/** accessKeyId */private static String accessKeyId;/** accessKeySecret */private static String accessKeySecret;/** 短信每天发送最大次数 */private static Integer sendMaxTime;/** 短信失效时间 */private static Long codeFailureTime;public static Integer getSendMaxTime() {return sendMaxTime;}public void setSendMaxTime(Integer sendMaxTime) {AliConfig.sendMaxTime = sendMaxTime;}public static Long getCodeFailureTime() {return codeFailureTime;}public void setCodeFailureTime(Long codeFailureTime) {AliConfig.codeFailureTime = codeFailureTime;}public static String getAccessKeyId() {return accessKeyId;}public void setAccessKeyId(String accessKeyId) {AliConfig.accessKeyId = accessKeyId;}public static String getAccessKeySecret() {return accessKeySecret;}public void setAccessKeySecret(String accessKeySecret) {AliConfig.accessKeySecret = accessKeySecret;}}

2.4 编写阿里工具类

package mon.utils.wx;import com.aliyuncs.DefaultAcsClient;import com.aliyuncs.IAcsClient;import com.aliyuncs.dysmsapi.model.v0525.SendSmsRequest;import com.aliyuncs.dysmsapi.model.v0525.SendSmsResponse;import com.aliyuncs.exceptions.ClientException;import com.aliyuncs.profile.DefaultProfile;import com.aliyuncs.profile.IClientProfile;public class AliyunSmsUtil {// 产品名称:云通信短信API产品,开发者无需替换static final String product = "Dysmsapi";// 产品域名,开发者无需替换static final String domain = "";static final String accessKeyId = AliConfig.getAccessKeyId();static final String accessKeySecret = AliConfig.getAccessKeySecret();public static SendSmsResponse sendCode(String mobile, String code) throws ClientException {// 可自助调整超时时间System.setProperty(".client.defaultConnectTimeout", "10000");System.setProperty(".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(mobile);// 必填:短信签名-可在短信控制台中找到// request.setSignName("兰考县人力资源和社会保障");request.setSignName("巩义人社");// 必填:短信模板-可在短信控制台中找到request.setTemplateCode("SMS_154500049");// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为request.setTemplateParam("{\"code\":\"" + code + "\"}");// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)// request.setSmsUpExtendCode("90997");// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者request.setOutId("yourOutId");// hint 此处可能会抛出异常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);return sendSmsResponse;}public static SendSmsResponse sendCode(String signName, String templateCode, String mobile, String code)throws ClientException {// 可自助调整超时时间System.setProperty(".client.defaultConnectTimeout", "10000");System.setProperty(".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(mobile);// 必填:短信签名-可在短信控制台中找到request.setSignName(signName);// 必填:短信模板-可在短信控制台中找到request.setTemplateCode(templateCode);// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为request.setTemplateParam("{\"code\":\"" + code + "\"}");// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)// request.setSmsUpExtendCode("90997");// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者request.setOutId("yourOutId");// hint 此处可能会抛出异常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);return sendSmsResponse;}public static int getCode() {return (int) ((Math.random() * 9 + 1) * 100000);}public static void main(String[] args) {try {sendCode("模板名", "SMS_*********", "手机号", getCode() + "");} catch (ClientException e) {e.printStackTrace();}}}

2.5 编写短信缓存

package mon.utils.wx;import java.util.HashMap;import java.util.Map;import java.util.concurrent.*;public class Cache {// 键值对集合private final static Map<String, Entity> map = new HashMap<>();// 定时器线程池,用于清除过期缓存private final static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();/*** 添加缓存** @param key* 键* @param data* 值*/public synchronized static void put(String key, Object data) {Cache.put(key, data, 0);}/*** 添加缓存** @param key* 键* @param data* 值* @param expire* 过期时间,单位:毫秒, 0表示无限长*/public synchronized static void put(final String key, Object data, long expire) {// 清除原键值对Cache.remove(key);// 设置过期时间if (expire > 0) {Future future = executor.schedule(new Runnable() {@Overridepublic void run() {// 过期后清除该键值对synchronized (Cache.class) {map.remove(key);}}}, expire, TimeUnit.MILLISECONDS);map.put(key, new Entity(data, future));} else {// 不设置过期时间map.put(key, new Entity(data, null));}}/*** 读取缓存** @param key* 键* @return*/public synchronized static Object get(String key) {Entity entity = map.get(key);return entity == null ? null : entity.getValue();}/*** 读取缓存** @param key* 键 * @param clazz 值类型* @return*/public synchronized static <T> T get(String key, Class<T> clazz) {return clazz.cast(Cache.get(key));}/*** 清除缓存** @param key* @return*/public synchronized static Object remove(String key) {// 清除原缓存数据Entity entity = map.remove(key);if (entity == null)return null;// 清除原键值对定时器Future future = entity.getFuture();if (future != null)future.cancel(true);return entity.getValue();}/*** 查询当前缓存的键值对数量** @return*/public synchronized static int size() {return map.size();}/*** 缓存实体类*/private static class Entity {// 键值对的valueprivate Object value;// 定时器Futureprivate Future future;public Entity(Object value, Future future) {this.value = value;this.future = future;}/*** 获取值** @return*/public Object getValue() {return value;}/*** 获取Future对象** @return*/public Future getFuture() {return future;}}}

2.6 编写发送短信随机码–6位数

public static int getCode(){return (int)((Math.random()*9+1)*100000);}

2.7 发送短信接口

@ApiOperation(value = "发送短信验证码", notes = "通过手机号发送短信,参数:手机号")@ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "15858585858", required = true, paramType = "form", dataType = "String"), })@GetMapping(value = "sendCode", produces = {"application/json;charset=UTF-8" })public AjaxResult sendCode(String mobile) {try {String code = getCode()+"";SendSmsResponse sr=AliyunSmsUtil.sendCode("模板名", "模板id",mobile, code);if("OK".equals(sr.getCode())) {Cache.put(mobile.trim(), code, 120000);String code11 = (String) Cache.get(mobile);return AjaxResult.success("发送成功");}} catch (ClientException e) {e.printStackTrace();}return AjaxResult.error("操作失败");}

2.8 校验验证码有没有过期

String oldCode = (String) Cache.get(mobile);if(StringUtils.isNotEmpty(oldCode)) {return AjaxResult.warn("之前验证码还没失效");}

2.9 判断手机号是否为空,手机格式是否有误

if(!isPhone(mobile)) {return AjaxResult.warn("手机号格式有误");}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) {//MToast.showToast("手机号应为11位数");return false;} else {Pattern p = pile(regex);Matcher m = p.matcher(phone);boolean isMatch = m.matches();//LogUtil.e(isMatch);if (!isMatch) {// MToast.showToast("请填入正确的手机号");}return isMatch;}}

2.10 验证成功后,移除缓存中的手机号验证码

Cache.remove(webUser.getMobile());

如果没啥意外,即可发送成功!

{"msg": "发送成功","code": 0}

3 修改短信接口

3.1 添加短信类型

@ApiOperation(value = "发送短信验证码", notes = "通过手机号发送短信,参数:手机号,type类别type 1.注册 2.修改密码 3.修改手机号 4 修改个人信息 5 忘记密码")@ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "15858585858", required = true, paramType = "form", dataType = "String"), @ApiImplicitParam(name = "type", value = "2", required = true, paramType = "form", dataType = "String"),})@GetMapping(value = "sendCode")public AjaxResult sendCode(String mobile,String type) {if(StringUtils.isNotBlank(mobile)&&StringUtils.isNotBlank(type)){//类别不为空的情况}else{//返回参数为空}

3.2 获取配置文件中短信时间跟最大次数

if(webSmsLogService.countByMobile(mobile)>AliConfig.getSendMaxTime()) {return AjaxResult.warn("当天接收验证码超限制");}

3.3 对特别类型下进行校验

/* * 1.注册:拿注册举例,如果用户表已经有了改用户,就没有必要给这个人发送短信,因为已经注册过* 2.忘记密码:如果用户表根本就没有这个手机号,就没有必要发忘记密码的短信--可以根据自己短信种类做判断。规避短信滥用*/if("1".equals(type)) {try {//判断该手机号是否已经存在--存在表示用户已经注册过,不存在的情况才能发注册的验证码if(webUserService.checkMobileSole(mobile)) {return AjaxResult.warn("手机号已经存在");}String oldCode = (String) Cache.get(mobile);if(StringUtils.isNotEmpty(oldCode)) {return AjaxResult.warn("之前验证码还没失效");}String code = getCode()+"";SendSmsResponse sr=AliyunSmsUtil.sendCode("模板名", "模板id",mobile, code);if("OK".equals(sr.getCode())) {if("OK".equals(sr.getCode())) {//发送成功将手机号 验证码 失效时间保存到Cache中Cache.put(mobile.trim(), code, AliConfig.getCodeFailureTime());return AjaxResult.success("发送成功");}} catch (ClientException e) {// TODO Auto-generated catch blocke.printStackTrace();return AjaxResult.error("调用阿里短信验证码失败");}}

3.4 动态设置失效时间

Cache.put(mobile.trim(), code, AliConfig.getCodeFailureTime());

3.5 规定时间内没有失效的校验

String oldCode = (String) Cache.get(mobile);if(StringUtils.isNotEmpty(oldCode)) {return AjaxResult.warn("之前验证码还没失效");}

3.6新建表,保存短信日志,

CREATE TABLE `sys_sms_log` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`phone` varchar(11) DEFAULT NULL COMMENT '手机号',`send_time` datetime DEFAULT NULL COMMENT '发送时间',`send_status` char(1) DEFAULT NULL COMMENT '发送状态:0失败;1成功',`content` varchar(100) DEFAULT NULL COMMENT '发送内容',`send_type` char(1) DEFAULT NULL COMMENT '调用方式:1.注册 2.修改密码 3.修改手机号 4 修改个人信息 5 忘记密码.',`result_code` varchar(50) DEFAULT NULL COMMENT '短信运营商的返回码',`send_bizId` varchar(50) DEFAULT NULL COMMENT '短信发送回执ID',`send_ip` varchar(20) DEFAULT NULL COMMENT '发送短信的IP地址',PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='短信发送日志'

每次发送成功后将信息保存短信日志表

SendSmsResponse sr=AliyunSmsUtil.sendCode("模板名", "模板id",mobile, code);if("OK".equals(sr.getCode())) {//发送成功将手机号 验证码 失效时间保存到Cache中Cache.put(mobile.trim(), code, AliConfig.getCodeFailureTime());String code11 = (String) Cache.get(mobile);WebSmsLog smslog = new WebSmsLog();smslog.setContent("");smslog.setPhone(mobile);smslog.setResultCode("OK");smslog.setSendBizid(sr.getRequestId());//smslog.setSendIp(sendIp);smslog.setSendStatus(1);smslog.setSendTime(DateUtils.getNowDate());smslog.setSendType(type);sysSmsLogService.insertSysSmsLog(smslog);return AjaxResult.success("发送成功");}

3.8 结果图

发送结果

4 注意点

4.1 模板签名正确性

AK --模板名--模板id这些都是对应的,项目多了有时候会把另外一个项目的AK拿到这个项目用,但是模板id却是这个项目的,尽量多审查几遍,保证模板设置要与控制台的短信模板相对应

4.2 授权问题

(遇到过一次)需要阿里后台点一下

4.3 尽量把次数,失效时间,AK写到配置文件,方便修改

4.4 谢谢点赞 ^o^

本人小白,以上是自己的一知半解,有任何问题请留言评论,及时改正,及时回复,互相学习互相进步。手打2小时,也希望对新手有帮助,看的开心话点赞关注。原创–转载请备明出处–叩谢!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。