2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 阿里大于短信——发送手机验证码

阿里大于短信——发送手机验证码

时间:2020-01-05 16:42:36

相关推荐

阿里大于短信——发送手机验证码

使用阿里大于的短信服务需要先去开通相应服务,具体过程:/article/171902.htm,/shubs/p/12092089.html

加依赖:

<!--阿里大于短信--><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.3</version></dependency>

然后拿到下面几个参数:

1、密钥:AccessKeyId、AccessKeySecret

2、模板CODE

3、短信签名(2和3在阿里云官网设置)

可以先去官网的OpenAPI Explorer中测试是否成功:

信息填好发送返回成功即可

再去看看官网是怎么发送请求的:

import monRequest;import monResponse;import com.aliyuncs.DefaultAcsClient;import com.aliyuncs.IAcsClient;import com.aliyuncs.exceptions.ClientException;import com.aliyuncs.exceptions.ServerException;import com.aliyuncs.http.MethodType;import com.aliyuncs.profile.DefaultProfile;/*pom.xml<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.3</version></dependency>*/public class SendSms {public static void main(String[] args) {DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>"); //密钥IAcsClient client = new DefaultAcsClient(profile);CommonRequest request = new CommonRequest();request.setSysMethod(MethodType.POST);request.setSysDomain("");request.setSysVersion("-05-25");request.setSysAction("SendSms");request.putQueryParameter("RegionId", "cn-hangzhou");try {//模板CODE、手机、签名等都在request中CommonResponse response = client.getCommonResponse(request); System.out.println(response.getData());} catch (ServerException e) {e.printStackTrace();} catch (ClientException e) {e.printStackTrace();}}}

发现很简单,我们就是把一些参数封装进request中,其他基本可以照抄:

@Slf4jpublic class SendSmsUtils {// 阿里云API密钥,注意空格private static String accessKeyId = "LTAI4FrRvd4jiP4EHy782";private static String accessSecret = "w7mImDkpvVorcKLL";//模板private static String templateCode= "SMS_202550742";//签名private static String signName = "ABC商城";/**** @param phoneNumber 接收手机号,可多个,验证码发送最好只一个手机号* @param signName 签名名称* @param templateCode 模板CODE* @param templateParam 模板参数,JSON字符串{code:123567}*/public static String SendMessage(String phoneNumber,String templateParam){DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);IAcsClient client = new DefaultAcsClient(profile);CommonRequest request = new CommonRequest();request.setSysMethod(MethodType.POST);request.setSysDomain("");request.setSysVersion("-05-25");request.setSysAction("SendSms");request.putQueryParameter("RegionId", "cn-hangzhou");// 接收手机号码,多个以逗号隔开request.putQueryParameter("PhoneNumbers", phoneNumber);// 签名名称request.putQueryParameter("SignName", signName);// 模板CODErequest.putQueryParameter("TemplateCode", templateCode);// 模板缺失内容request.putQueryParameter("TemplateParam", templateParam);try {CommonResponse response = client.getCommonResponse(request);System.out.println(response.getData());return response.getData();} catch (ServerException e) {e.printStackTrace();return null;} catch (ClientException e) {e.printStackTrace();return null;}}}

这样我们在controller中调用该方法即可发送成功:

@AutowiredSmsService smsService;@ApiOperation("获取手机验证码")@GetMapping("/sms")@ApiImplicitParam(value = "手机号",name = "phone",required = true,dataType = "string",paramType = "query")public String getSMSCode(@RequestParam("phone") String phone){//向验证码服务请求发送验证码return smsService.sendMsg(phone);}

上面是一个简单的发送验证码的例子,验证码一般是用于登陆/注册时用到,而真实的项目,可以在接到请求时在后台生成验证码,然后将其放到redis中(设置过期时间),在用户收到验证码时则填写完发到后端,此时再去和redis中的验证码进行对比。

然而这样还是有多个问题需要考虑:

1、前端中请求验证码的接口暴露,可能被恶意刷接口

2、用户多次请求,重复请求(接口幂等性)

3、换ip/手机去刷

前端控制每60分钟发送一次,在接口调用时添加图形验证码(在提交时增加图片验证码来限制机器请求,一般图片验证码可以防止大部分的机器刷码)、单ip请求限制、限定每天每个号码获取短信验证码的次数、限制短信验证码的调用频率等

正常用户重复请求可以前端控制60s一次就可以了,也可以利用token机制,在前端和后端(redis)放同一个码,每次请求过来检验通过才给发验证码。

如果使用token机制还需要考虑另一个点,当数据要求比较严格时,如订单提交的幂等性,此时如果系统是分布式,考虑到并发高、且数据要求严格,此时则要对其token加上分布式锁,以保证只有一个进程拿到redis中的token并进行后面的操作。

当然一个接口保证幂等性除了token机制,还可以在后端维护一个重复表,每次请求来看下有没有重复的,重复的则不进行处理,

还有一些对数据库的操作本身是具有幂等性的,如查询,更新删除时不对值进行增量计算(例不要用a+=2,或-1等变量操作)

!!!!!!!!!!!!!!!!!扯太远了

(如果是订单的别忘了要考虑分布式事务的处理啊)

/weixin_4666/article/details/89680342

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