springboot整合阿里云短信,同时验证码存入Redis教程(后端详细教程,亲身实践)

调用阿里云短信验证,将验证码存入Redis,设置过期时间;

开始前要注册阿里云账号和创建Access Key,有以下四个信息

'accessKeyId' = '#####',  //key
'accessSecret' = '#####',  //secret
'SignName' = '####', //短信标签
'verifyCode_common' = '#####', //短信模版

一、在pom.xml中添加阿里云短信和Redis依赖

(注意:aliyun-java-sdk-dysmsapi、aliyun-java-sdk-core版本不能过高,我开始用的版本4的,工具类使用会报错)
<!--  阿里云短信依赖  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>1.0.0</version>
        </dependency>
  <!-- redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
      
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

二、在application.yml/application.properties文件中配置Redis相关参数

  redis:
    key:
      prefix:
        authCode: "portal:authCode:"
        orderId: "portal:orderId:"
      expire:
        authCode: 60 # 验证码超期时间
    host: 127.0.0.1 # Redis服务器地址
    database: 0 # Redis数据库索引(默认为0)
    port: 6379 # Redis服务器连接端口
    password: # Redis服务器连接密码(默认为空)
    jedis:
      pool:
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 8 # 连接池中的最大空闲连接
        min-idle: 0 # 连接池中的最小空闲连接
    timeout: 3000ms # 连接超时时间(毫秒)

三、添加Redis相关文件,service文件夹下创建RedisService,RedisServiceImpl,service文件夹同级创建config文件夹,创建RedisConfiguration文件,复制以下对应代码;


public interface RedisService {

    /**
     * 存储数据
     */
    void set(String key, String value);

    /**
     * 获取数据
     */
    String get(String key);

    /**
     * 设置超期时间
     */
    boolean expire(String key, long expire);

    /**
     * 删除数据
     */
    void remove(String key);

    /**
     * 自增操作
     * @param delta 自增步长
     */
    Long increment(String key, long delta);

}

@Service
public class RedisServiceImpl implements RedisService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void set(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    @Override
    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    @Override
    public boolean expire(String key, long expire) {
        return stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
    }

    @Override
    public void remove(String key) {
        stringRedisTemplate.delete(key);
    }

    @Override
    public Long increment(String key, long delta) {
        return stringRedisTemplate.opsForValue().increment(key,delta);
    }

}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfiguration {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate<>();
        //设置redis的连接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

四、工具文件夹下添加验证码生成工具CodeUtil 、短信发送工具SmsTool,SmsTool中替换自己的Access Key的id、secret、signName、TemplateCode。

import java.util.Random;

public class CodeUtil {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }

    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
        }
        return verifyCode.toString();
    }

    public static void main(String[] args) {
        System.out.println(generateVerifyCode(4));
    }
}
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;

public class SmsTool {

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";
//     TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
    static final String accessKeyId = "#########";
    static final String accessKeySecret = "###########";


    public static SendSmsResponse sendSms(String phone , 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(phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName("#####");
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode("#########");
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam(code);

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        //request.setOutId("yourOutId");

        //hint 此处可能会抛出异常,注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        return sendSmsResponse;
    }
}

五、控制层添加文件SmsCtrlController

import com.alibaba.druid.util.StringUtils;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.springboot.service.RedisService;
import com.springboot.util.CodeUtil;
import com.springboot.util.SmsTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/sms")
public class SmsCtrlController {


    /***
     * 注入redis模版
     */
    @Autowired
    private RedisService redisService;
    private  String tokenId="TOKEN-USER-";


    /**
     * 发送短信
     * @ResponseBody 返回json数据
     * @RequestMapping 拦截请求,指定请求类型:POST
     * @RequestBody 接受前台传入的json数据 接受类型为Map
     * @throws ClientException 抛出异常
     */
    @ResponseBody
    @PostMapping("/smsXxs")
    public Map<String,Object> smsXxs(@RequestBody Map<String,Object> requestMap) throws ClientException {
        Map<String,Object> map = new HashMap<>();

        String phone = requestMap.get("phone").toString();
            System.out.println(phone);

            // 调用工具栏中生成验证码方法(指定长度的随机数)
            String code = CodeUtil.generateVerifyCode(6);

            //填充验证码
            String TemplateParam = "{\"code\":\""+code+"\"}";
        SendSmsResponse response = SmsTool.sendSms(phone,TemplateParam);//传入手机号码及短信模板中的验证码占位符

            map.put("verifyCode",code);
            map.put("phone",phone);

            System.out.println(response.getCode());
        if( response.getCode().equals("OK")) {
            map.put("isOk","OK");
            //验证码绑定手机号并存储到redis
            redisService.set(tokenId+phone,code);
            redisService.expire(tokenId+phone,620);//调用reids工具类中存储方法设置超时时间
        }

        return map;
    }


    /**
     * 注册验证
     * @ResponseBody 返回json数据
     * @RequestMapping 拦截请求,指定请求类型:POST
     * @RequestBody 接受前台传入的json数据 接受类型为Map
     * @throws ClientException 抛出异常
     */
    @ResponseBody
    @PostMapping("/validateNum")
    public Map<String, Object> validateNum(@RequestBody Map<String,Object> requestMap) throws ClientException {
        
        Map<String,Object> map = new HashMap<>();

        String phone = requestMap.get("rPhone").toString();//获取注册手机号码
       
        String verifyCode = requestMap.get("identifyCode").toString();//获取手机验证码

        //首先比对验证码是否失效
        String redisauthcode= redisService.get(tokenId+phone); //传入tonkenId返回redis中的value
        if(StringUtils.isEmpty(redisauthcode)){
            //如果未取到则过期验证码已失效
            map.put("result",404);
        }else  if(!"".equals(redisauthcode)&&!verifyCode.equals(redisauthcode)){
            //验证码错误
            map.put("result",500);
        }else{
            //用户注册成功
            map.put("result",200);
        }
        return map;
    }

}

六、启动服务器即可,从前端发送手机号到/sms/smsXxs请求,生成验证码存入Redis,点击注册将注册信息发送到/sms/validateNum请求即可,springboot项目调用阿里云短信业务就完成啦。

过程中有问题可以留言*^_^*

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值