springboot-springsecurity调用阿里云API发送短信验证码实现账号注册

背景:

最近和前端小伙伴一起搭建一个个人博客网站,注册功能为防止恶意破解密码、博客灌水等,在注册时做到手机号唯一且为本人手机号,故采用了阿里云的短信验证码(之前试过邮箱发送验证码,不知道为啥,经常被当垃圾邮件给拦截)

步骤:

  1. 登录阿里云,选择短信服务(可直接搜索短信服务)在这里插入图片描述
  2. 点击开通短服务(点击免费开通 我这采用的是用多少给多少 并不是买套餐 感觉我的网站用户量达不到那么大)
    在这里插入图片描述
    3.进入快速学习模块,如果没有签名和模板请自行参照帮助文档提供的规范来申请,一般来说一两个小时就能审批下来


4.签名和模板都审批下来了,最重要的就是先往阿里云充点钱,不然用不了,别问我为什么,问马爸爸 噢 张爸爸去。。
5.鼠标移至右上角头像处,你会看见accesskeys,弹出安全提示,点击继续使用AccessKeys,创建你的accesskey,注意要记住自己的AccessKeyId和AccessKeySecret后面会有用到
6.好啦,阿里云上的部分就是这些,下面开始进入代码部分

首先引入maven插件

 <!--阿里云短信服务-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.0.6</version>
        </dependency>

        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>1.1.0</version>
        </dependency>

就这两个足矣

然后我们创建一个AliyunSmsUtils

package com.zty.blog.util;

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;
import com.aliyuncs.profile.IClientProfile;

/**
 * @author  zty
 * 阿里云短信服务:
 * 注意:需要 签名名称、模版CODE 以及 RAM访问控制中的 AccessKeyID 和 AccessKeySecret
 * 如果是发送验证码 除了我标出的部分 无需修改其他的
 */
public class AliyunSmsUtils {

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";
   
    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
    static final String accessKeyId = "输入自己的accesskeyId";  // TODO 修改成自己的
    static final String accessKeySecret = "输入自己的accesskeySecret";   // TODO 修改成自己的
    public static SendSmsResponse sendSms(String telephone, String code) throws ClientException {
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.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(telephone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName("修改为自己的签名");    // TODO 修改成自己的
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode("修改为自己的模板CODE");    // TODO 修改成自己的
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//        request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"123\"}");
        request.setTemplateParam("{\"code\":\"" + code + "\"}");//如果为发送验证码 无需修改
        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");
        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        //hint 此处可能会抛出异常,注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        if(sendSmsResponse.getCode()!= null && sendSmsResponse.getCode().equals("OK")){
            System.out.println("短信发送成功!");
        }else {
            System.out.println("短信发送失败!");
        }
        return sendSmsResponse;
    }



}

接下来就是调用这个工具类发送短信了

验证码单独写一个工具类(用于生成一个五位数验证码)

package com.zty.blog.util;

import java.util.Random;

/**
 * @author: zty
 * @date 2019/10/5 下午2:33
 * @description: 生成10000-99999的随机数
 */
public class RandomUtil {
    public static int returnCode() {
        Random rand = new Random();
        return rand.nextInt(89999) + 10000;
    }

}

短信的过期时间控制采用redis缓存来实现
获取验证码用Get请求就行了
如果用springsecurity 记得打开该接口的权限

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.zty.blog.dao.UserMapper;
import com.zty.blog.enums.ResultEnum;
import com.zty.blog.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import static com.zty.blog.util.AliyunSmsUtils.sendSms;

/**
 * @author: zty
 * @date 2019/10/6 下午1:33
 * @description:
 */
@RestController
@Slf4j
@RequestMapping("/code")
@Api(tags = "验证码生成接口")
@CrossOrigin
public class SecurityCodeController {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserMapper userMapper;

    @GetMapping("/getCode")
    @ApiOperation("获取验证码")
    public Object getCode(@RequestParam String username) throws ClientException {
        boolean isHave = (userMapper.selectUserByUsername(username) != null);
        if (isHave){
            return ResultVOUtil.error(ResultEnum.USER_HAS_EXIST);
        }if (redisUtil.get(username)!=null){
            redisUtil.del(username);
        }
        String optCode = String.valueOf(RandomUtil.returnCode());
        redisUtil.set(username, optCode, 300);
        //这里由于没有用短信发送 为了获取验证码是多少 我们打印到控制台
        SendSmsResponse response =sendSms(username,optCode); // TODO 填写你需要测试的手机号码
        log.info("短信接口返回的数据----------------");
        log.info("Code=" + response.getCode());
        log.info("Message=" + response.getMessage());
        log.info("RequestId=" + response.getRequestId());
        log.info("BizId=" + response.getBizId());
        return ResultVOUtil.success();
    }
}

测试

在这里插入图片描述
在swagger中进行测试
在这里插入图片描述

成功得到

发布了22 篇原创文章 · 获赞 28 · 访问量 2659

猜你喜欢

转载自blog.csdn.net/qq_43561507/article/details/103012402