使用阿里云短信推送服务发送验证码

前言

最近课程项目做一个网站,需要实现注册、忘记密码等功能的推送验证码的功能

而且根据相关法律法规,用户也需要手机号认证…(反正很多网站都是这么说的)

介绍

本来想弄一个免费的短信服务商,http://www.mob.com/product/sms这家就挺不错的,支持还挺全,有

  • IOS
  • Android
  • Unity3d
  • Cocos2d
  • flutter
  • apicloud

而且都是免费的!

但是没有web

客服回答说要有APP,要上线,要充值,每条五分…瞬间没了好感

而且不管使用什么SDK都要实名认证,身份证照片啊,手持身份证照片啊,说实话把这些信息给这些小企业有点信不过

使用阿里云短信推送服务发送验证码_第1张图片

开始准备看看他们提供的Android源码,你不也是调用API去发送短信吗,那我就把这个接口给 偷过来 窃过来不就可以了

当我一层一层地点开各种方法时,看到的都是类似下图这种a啊,b啊的方法名,还有参数也不明白意思,看来做了混淆防止反编译,算了,我这点渣渣水平就不去像这种骚操作了。

如果真的不想花钱的话,可以找一台手机(安卓或IOS)使用它们的SDK,然后从网站上去唤醒这个手机发送验证码的功能,间接使用,当然速度会很慢啊,手机一直联网可能会断网啊,增加开发手机端的代码量啊很多缺点,但是不要钱也是很香的

使用阿里云短信推送服务发送验证码_第2张图片

还是决定老老实实用付费的吧

这个选择就多了去了,普遍是0.05元一条,有的小网站可以做到0.03元左右,还是用大服务商的吧,稳定信得过,什么阿里云,腾讯云,百度云,网易云啥的都有

这里我选择的是阿里云

顺便说一下,良心的亚马逊云AWS也有免费的短信包,之前我就一直在用这个测试,但是后来才发现只有美国的手机号码才免费,于是花了我0.1美元…

资费

定价如下,可以选择套餐包或者预付费,不过套餐是5000条起卖225元(emmmm对于我们这种蚊子型网站有点浪费啊)所以还是选择预付费吧,用多少付多少

使用阿里云短信推送服务发送验证码_第3张图片

而且新开通的用户还会送100条短信,估计是考虑到测试的需要

1557994534479

开通链接

然后需要两个基本的东西,一个是签名,一个是模板

如下

  • 签名就是【】框里的东西
  • 模板就是【】框后面的内容,可以有变量

使用阿里云短信推送服务发送验证码_第4张图片

添加签名

然后进入控制台->短信服务->国内消息->添加签名,可以看到我已经添加了一条签名

使用阿里云短信推送服务发送验证码_第5张图片

签名填写服务的名称,场景选择验证码(通用类型需要验证很多东西),申请说明是给审核人员看的,一般两小时会完成审核

使用阿里云短信推送服务发送验证码_第6张图片

添加模板

选择模板管理->添加模板

使用阿里云短信推送服务发送验证码_第7张图片

选择验证码

输入模板名称(这个名称是给自己看的不会出现在短信中)

输入模板内容(可以有变量,用${}包起来,发短信的时候可以动态控制)

还有申请说明

使用阿里云短信推送服务发送验证码_第8张图片

测试发送

当签名和模板都审核通过后

点击快速学习,使用给定的签名和模板进行测试,填入变量和手机号码,点击发送短息就可以测试发送消息

另外这个查看API Demo会提供各种代码调用API的示例,方便整合进自己的服务中,后面还会用到

使用阿里云短信推送服务发送验证码_第9张图片

添加访问密钥

使用代码调用API时,要通过accessKeyIdsecret验证身份

点击右上角个人头像,选择访问控制

为什么是点访问控制而不是accesskeys呢?

  • 因为accesskeys里面也会建议你使用子用户进行访问。

那为什么要子用户进行访问呢?

  • 比如在阿里云开通了很多付费服务都需要accesskey验证,如果使用主账户的accesskey不小心泄露了,那么所有的付费服务都被泄露了,可能带来很大的财产损失和信息丢失
  • 如果使用子用户就可以动态控制每个用户的权限,比如a用户只有发短息的权限,再不济泄露了也不会影响其他的服务,将损失降为最小

使用阿里云短信推送服务发送验证码_第10张图片

选择用户->新建用户,可以看到我已经建立了两个用户分别用于短信和邮件服务

使用阿里云短信推送服务发送验证码_第11张图片

写好登录名称,显示名称,勾选编程访问就好了,如果是控制台登录的话其实就相当于一个阿里云账户可以在网站上登录,这个暂时不需要

使用阿里云短信推送服务发送验证码_第12张图片

下图中的AccessKeyIDAccessKeySceret就是编程需要的参数了

不要试图使用我的这个AccessKey干坏事哦,因为 我账户里没钱 它已经被删掉啦

需要注意的是账号一旦创建完成,就再也看不到它们了,所以要提前点击复制或者下载CSV文件进行备份

然后再点击添加权限

使用阿里云短信推送服务发送验证码_第13张图片

对于短信推送

输入sms进行搜索,选择AliyunDysmsFullAccess ,点击确定

使用阿里云短信推送服务发送验证码_第14张图片

使用代码调用短信服务

回到控制台->短信服务->快速学习,点击查看API DEMO

使用阿里云短信推送服务发送验证码_第15张图片

在右侧选择需要的语言,将代码全部复制下来

使用阿里云短信推送服务发送验证码_第16张图片

添加依赖

JAVA为例

因为使用的api是阿里云自家的,所以官方默认jar肯定是没有

maven为例

dependencies中添加依赖,这个依赖在API DEMO中的注释部分给了出来,如


    com.aliyun
    aliyun-java-sdk-core
    4.1.0

使用阿里云短信推送服务发送验证码_第17张图片

完整代码

//填入有短信推送服务权限的AccessKey id和secret
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "", "");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
//设置https调用
//request.setProtocol(ProtocolType.HTTPS);
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", "12233334444");
//之前申请的签名名称
request.putQueryParameter("SignName", "TimeIsMoney");
//之前申请的模板CODE
request.putQueryParameter("TemplateCode", "SMS_165380907");
//模板里面的变量赋值,使用JSON格式
request.putQueryParameter("TemplateParam", "{\"code\":\"6666\"}");
try {
    CommonResponse response = client.getCommonResponse(request);
    System.out.println(response.getData());
} catch (ServerException e) {
    e.printStackTrace();
} catch (ClientException e) {
    e.printStackTrace();
}

密钥安全保障

如果是开源项目的话,这样子会直接把密钥暴露在互联网中,相当不安全,所以需要做一点措施,把密钥和代码分开

resources包里添加包privateKey

使用阿里云短信推送服务发送验证码_第18张图片

在这个包里新建SMSKey.txt存储密钥

写上两行数据,一行是ID一行是secret

1558000026585

修改代码,添加两个私有变量accessKeyIdsecret,并且在静态代码块里把它们赋值为txt中的值

private static final String accessKeyId;
private static final String secret;
/**
 * 初始化获取私钥
 * */
static {
    ClassPathResource smsKey = new ClassPathResource("privateKey/SMSKey.txt");
    System.out.println(smsKey);
    Scanner scanner = null;
    try {
        scanner = new Scanner(smsKey.getInputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
    accessKeyId = scanner.nextLine();
    secret = scanner.nextLine();
    scanner.close();
}

然后调用的时候使用这两个变量就好了

DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret);

邮件的密钥同理

还有一步,不能把这两个txt文件也传到git仓库中去

gitignore中添加

EmailKey.txt
SMSKey.txt

现在就可以安心地把代码push上去了。

另外这只是开源代码遇到的问题,如果真的部署到了服务器,还会有以下问题值得思考

  • 获取验证码的网站页面,没有做防止非法获取验证码的措施,比如最简单的图形校验码。(常见于网站上获取验证码)

    建议:点击获取验证码之前做一个校验,比如需要正确输入图形验证码、拖动验证等

  • 发送短信的接口暴露,且没有做加密措施,遭受恶意调用。(此类常见于APP侧获取验证码)

    建议:在短信接口做一些加密措施(例如加入图形验证等方式),防止非法调用。

效果

使用阿里云短信推送服务发送验证码_第19张图片

你可能感兴趣的:(Server)