短信发送(阿里云短信服务)

2,069 阅读7分钟

一、短信发送

阿里云短信服务

  1. 短信服务介绍

    在项目中,如果我们要实现短信发送功能,我们无需自己实现,也无需和运营商直接对接,只需要调用
    第三方提供的短信服务即可。目前市面上有很多第三方提供的短信服务,这些第三方短信服务会和各个
    运营商(移动、联通、电信)对接,我们只需要注册成为会员,并且按照提供的开发文档进行调用就可
    以发送短信。需要说明的是,这些短信服务一般都是收费服务。
    
    
    阿里云短信服务官方网站: https://www.aliyun.com/product/sms?spm=5176.19720258.J_8058803260.52.5c432c4a11Dcwf
    
  2. 阿里云短信服务准备

1.注册账号 阿里云官网:https://www.aliyun.com/
2.开通短信服务
注册成功后,点击登录按钮进行登录。登录后进入控制台, 在左上角的菜单栏中搜索短信服务。
第一次使用,需要点击,并开通短信服务。
3.设置短信签名
开通短信服务之后,进入短信服务管理页面,选择国内消息菜单,我们需要在这里添加短信签名。
        
那么什么是短信签名呢?
        
短信签名是短信发送者的署名,表示发送方的身份。
我们要调用阿里云短信服务发送短信,签名是比不可少的部分。

image.png

image.png
4.设置短信模板

切换到【模板管理】标签页:
        
那么什么是模板呢?

短信模板包含短信发送内容、场景、变量信息。模板的详情如下:
            
最终我们,给用户发送的短信中,具体的短信内容,就是下面图中配置的这个模板内容,
将${code}占位符替换成对应的验证码数据即可。
            
如下:我们可以点击右上角的按钮,添加模板,然后填写模板的基本信息及设置的模板内容:【xxxxx】

您好,您的验证码为173822,5分钟之内有效,不要泄露给他人!
image.png

image.png

image.png

5. 设置AccessKey

AccessKey 是访问阿里云 API 的密钥,具有账户的完全权限,
我们要想在后面通过API调用阿里云短信服务的接口发送短信,那么就必须要设置AccessKey。
我们点击右上角的用户头像,选择"AccessKey管理",这时就可以进入到AccessKey的管理界面。

进入到AccessKey的管理界面之后,
提示两个选项 "继续使用AccessKey""开始使用子用户AccessKey",两个区别如下:

1.继续使用AccessKey
    创建的是阿里云账号的AccessKey,是具有账户的完全权限,可以通过API调用阿里云的服务,
    不仅是短信服务,其他服务(OSS,语音服务,内容安全服务,视频点播服务...等)也可以调用。
    一旦AccessKey泄露,不太安全

2.开始使用子用户AccessKey
    可以创建一个子用户,这个子用户我们可以分配比较低的权限,比如仅分配短信发送的权限,
    不具备操作其他的服务的权限,即使这个AccessKey泄漏了,也不会影响其他的云服务, 相对安全。

演示如何创建子用户AccessKey。 image.png

image.png

6. 配置权限

上述我们已经创建了子用户, 但是这个子用户,目前没有任何权限,接下来,我们需要为创建的这个用户来分配权限。如下图:

经过上述的权限配置之后,那么新创建的这个 reggie 用户,仅有短信服务操作的权限,不具备别的权限,
即使当前的AccessKey泄漏了,也只会影响短信服务,其他服务是不受影响的。

image.png

7.禁用/删除AccessKey

如果在使用的过程中 AccessKey 不小心泄漏了,我们可以在阿里云控制台中, 禁用或者删除该AccessKey。

然后再创建一个新的AccessKey, 保存好AccessKeyId和AccessKeySecret。

image.png

image.png

二、代码开发

  1. 使用阿里云短信服务发送短信,可以参照官方提供的文档即可。

官方文档: help.aliyun.com/product/442…

  1. 根据官方文档的提示,引入对应的依赖,然后再引入对应的java代码,就可以发送消息了。

image.png

SDK : SDK 就是 Software Development Kit 的缩写,翻译过来——软件开发工具包,
辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做SDK。
在我们与第三方接口相互时, 一般都会提供对应的SDK,来简化我们的开发。

具体实现:

1. 引入依赖

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.5.16</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>2.1.0</version>
</dependency>

2. 将官方提供的main方法封装为一个工具类

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;
/**
 * 短信发送工具类
 */
public class SMSUtils {
   /**
    * 发送短信
    * @param signName 签名
    * @param templateCode 模板
    * @param phoneNumbers 手机号
    * @param param 参数
    */
   public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){
      DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou","xxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxx");
      IAcsClient client = new DefaultAcsClient(profile);
      SendSmsRequest request = new SendSmsRequest();
      request.setSysRegionId("cn-hangzhou");
      request.setPhoneNumbers(phoneNumbers);
      request.setSignName(signName);
      request.setTemplateCode(templateCode);
      request.setTemplateParam("{"code":""+param+""}");
      try {
         SendSmsResponse response = client.getAcsResponse(request);
         System.out.println("短信发送成功");
      }catch (ClientException e) {
         e.printStackTrace();
      }
   }
}

备注 : 由于我们个人目前无法申请阿里云短信服务,所以这里我们只需要把流程跑通,具体的短信发送可以实现。

手机验证码登录

登录流程: 输入手机号 > 获取验证码 > 输入验证码 > 点击登录 > 登录成功

1.短信工具类

具体实现第2步已经提供

2.验证码生成工具类

/**
 * 随机生成验证码工具类
 */
public class ValidateCodeUtils {
    /**
     * 随机生成验证码
     * @param length 长度为4位或者6位
     * @return
     */
    public static Integer generateValidateCode(int length){
        Integer code =null;
        if(length == 4){
            code = new Random().nextInt(9999);//生成随机数,最大为9999
            if(code < 1000){
                code = code + 1000;//保证随机数为4位数字
            }
        }else if(length == 6){
            code = new Random().nextInt(999999);//生成随机数,最大为999999
            if(code < 100000){
                code = code + 100000;//保证随机数为6位数字
            }
        }else{
            throw new RuntimeException("只能生成4位或6位数字验证码");
        }
        return code;
    }

    /**
     * 随机生成指定长度字符串验证码
     * @param length 长度
     * @return
     */
    public static String generateValidateCode4String(int length){
        Random rdm = new Random();
        String hash1 = Integer.toHexString(rdm.nextInt());
        String capstr = hash1.substring(0, length);
        return capstr;
    }
}

3.功能实现

1.获取验证码的实现

1. 修改LoginCheckFilter

在进行手机验证码登录时,发送的两个请求(获取验证码和登录)需要在此过滤器处理时直接放行。

2. 在过滤器中判定登录的状态

在LoginCheckFilter 中进行判定,如果移动端用户已登录,我们获取到用户登录信息,
存入ThreadLocal中(在后续的业务处理中,如果需要获取当前登录用户ID,直接从ThreadLocal中获取),然后放行。

3. 发送短信验证码

在controller中创建方法,处理登录页面的请求,
为指定手机号发送短信验证码,同时需要将手机号对应的验证码保存到Session,方便后续登录时进行比对。
    
    1.在参数中通过@RequestBody 接受手机号,通过HttpSession 注入session。
    2.通过StringUtils.isNotEmpty(phone)判断手机号是否存在,如果存在,生成4位验证码,不存在返回错误信息。
    3.调用阿里云提供的短信服务API完成发送短信。 SMSUtils.sendMessage("签名名称","",phone,code);
    4.需要将生成的验证码保存到Session。 session.setAttribute(phone,code);
    5.返回成功信息
  1. 登录并验证验证码的实现
1). 获取前端传递的手机号和验证码 (@RequestBody Map map, HttpSession session接受)
2). 从Session中获取到手机号对应的正确的验证码
3). 进行验证码的比对 , 如果比对失败, 直接返回错误信息
4). 如果比对成功, 需要根据手机号查询当前用户, 如果用户不存在, 则自动注册一个新用户
5). 将登录用户的ID存储Session中, 返回成功消息