阿里云发送短信

1.具备条件

1.阿里云开通短信服务

进入阿里云搜索短信就有对应的短信服务,支付宝购买后进入短信控制台,会有对应的短信服务等信息。包括国内学习、业务统计、系统设置等。

注意:签名和模板不支持个人用户申请未上线业务

阿里云发送短信_第1张图片

 2.控制台测试

填写对应信息即可,手机就会收到验证码信息。

阿里云发送短信_第2张图片

 2.java整合短信服务

1.代码开发

1.获取 AccessKey和secret-key

因为之前做oss对象存储的时候已经获取过AccessKey和secret-key,所以需要在用户中绑定并授权短信服务即可。

阿里云发送短信_第3张图片

 2.SpringBoot整合阿里云短信

首先看下官方文档的介绍与说明。

1.pom文件


  com.aliyun
  dysmsapi20170525
  2.0.18

2.配置文件

阿里云发送短信_第4张图片

 spring.cloud.nacos.discovery.server-addr:nacos服务注册地址

 alicloud.secrect-key:密钥

 alicloud.access-key:密钥

 sms.endpoint:地域节点

 sms.templateCode:模板

3.封装组件

其实就是把官方文档的代码拿过来自己用。

@Component
@Data
@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms") //和配置文件绑定
public class SmsComponent {

//    private String host;
//    private String path;
//    private String templateId;
//    private String appcode;


    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;
    @Value("${spring.cloud.alicloud.secret-key}")
    private String accessKey;

    /**
     * 配置文件对应的
     */
    private String endpoint;
    private String templateCode;
//
    public void sendSmsCode(String phone,String code) throws Exception {
//
//
//        String method = "POST";
//
//        Map headers = new HashMap();
//        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
//        headers.put("Authorization", "APPCODE " + appcode);
//        //根据API的要求,定义相对应的Content-Type
//        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
//        Map querys = new HashMap();
//        Map bodys = new HashMap();
//        bodys.put("mobile", phone);
//        bodys.put("tag", code);
//        bodys.put("templateId", templateId);
//
//
//        try {
//
//            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
//            System.out.println(response.toString());
//            //获取response的body
//            System.out.println(EntityUtils.toString(response.getEntity()));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

        Config config = new Config()
                // 您的 AccessKey ID
                .setAccessKeyId(accessId)
                // 您的 AccessKey Secret
                .setAccessKeySecret(accessKey);
        // 访问的域名
        config.endpoint = endpoint;
        Client client = new Client(config);
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setSignName("阿里云短信测试")
                .setTemplateCode(templateCode)
                .setPhoneNumbers(phone)
                .setTemplateParam("{\"code\":\""+code+"\"}");
        RuntimeOptions runtime = new RuntimeOptions();
        SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
        System.out.println(sendSmsResponse);
    }

}

4.发送短信接口

  @ResponseBody
    @GetMapping("/sms/sendCode")
    public R sendCode(@RequestParam("phone") String phone) throws Exception {
        String redisCode = stringRedisTemplate.opsForValue().get(AuthConstant.SMS_CODE_CACHE_PREFIX + phone);
        if (!StringUtils.isEmpty(redisCode)) {

            long currentTime = Long.parseLong(redisCode.split("_")[1]);
            //系统时间减去当前时间小于60s不能发送
            if (System.currentTimeMillis() - currentTime < 60000) {
                return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(), BizCodeEnum.SMS_CODE_EXCEPTION.getMsg());
            }
        }
        //接口防刷
        //验证码的再次校验 redis保存 存key->手机号 value->验证码   sms:code:1234567898--->123456
        String code = UUID.randomUUID().toString().substring(0, 5);
        String subString = code + "_" + System.currentTimeMillis();
        //redis缓存验证码 防止同一个手机号在60s内再次发送验证码
        stringRedisTemplate.opsForValue().set(AuthConstant.SMS_CODE_CACHE_PREFIX + phone, subString, 10, TimeUnit.MINUTES);
        feignService.sendCode(phone, code);
        return R.ok();
    }

 需要将前端传递的手机号进行发送短信收取验证码判断,如果redis中为空调取短信发送服务(通过feign),如果redis不为空,判断系统时间减去当前时间小于60s不能发送,这样有效防止接口防刷恶意操作。前端注册通过手机号调起后端接口,后端通过uuid等技术生成验证码并调取短信服务接口,使用户收取验证码。

3.MD5&MD5盐值加密

1.MD5

Message Digest algorithm 5,信息摘要算法

  1. 压缩性:任意长度的数据,算出的 MD5 值长度都是固定的;
  2. 容易计算:从原数据计算出 MD5 值很容易;
  3. 抗修改性:对原数据进行任何改动,哪怕只修改 1 个字节,所得到的 MD5 值都有很大区别;
  4. 强抗碰撞:想找到两个不同的数据,使它们具有相同的 MD5 值是非常困难的;
  5. 不可逆
 @Test
    void contextLoads() {


//        e10adc3949ba59abbe56e057f20f883e
//        md5不能直接用来存储加密密码
        //可破解 值一直不变 抗修改性: 利用彩虹表 暴力破解法

//        盐值加密
//        String s = DigestUtils.md5Hex("123456");
//        System.out.println(s);
//
//        //加盐:$1$+八位字符  每次盐值加密不一样
//        String s1 = Md5Crypt.md5Crypt(s.getBytes(),"$1$qwertyui");//$1$qwertyui$vP2GtrM4.h4RUK.3HGS9J.
//        System.out.println(s1);//

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode("123456");
//        $2a$10$1lc96GWrG7.Lte4f9FsniOAUbpc4t4oaPhXpyG3OiLAxrfsjXqdB6
//        $2a$10$2gXOTIfzQDw4VYKhKWNWreNUxCiySPnhAhJiCVLTaXyo6vlPGDPbS
        boolean matches = bCryptPasswordEncoder.matches("123456", "$2a$10$2gXOTIfzQDw4VYKhKWNWreNUxCiySPnhAhJiCVLTaXyo6vlPGDPbS");
        System.out.println(encode+"========>"+matches);

    }

encode产生的和123456始终都会匹配。

 @Override
    public MemberEntity login(MemberLoginVo vo) {
        //获取用户名
        String loginAccount = vo.getLoginAccount();
        //获取用户的密码
        String pagePassword = vo.getPassword();

        //去数据库查询
        MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper().eq("username", loginAccount).or().eq("mobile", loginAccount));
        if (memberEntity == null) {
            //登录失败
            return null;
        } else {
            //从数据库返回的密码字段值
            String password = memberEntity.getPassword();

            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            //用页面提交的代码和数据库注册的盐值进行匹配
            boolean b = passwordEncoder.matches(pagePassword, password);
            if (b) {
                return memberEntity;
            } else {
                return null;
            }
        }

你可能感兴趣的:(阿里云,maven,spring,boot,spring,cloud)