通过uniCloud云函数发送手机验证码

907 阅读3分钟

技术点总结

SpringBoot redis uniCloud云函数

为什么使用uniCloud云函数?

因为阿里云腾讯云现在特别严 我他妈签名和模板申请不下来

实现步骤

  1. 实现uniCloud云函数【uniCloud控制台给每一个云函数都是可以 url化】
  2. maven引入依赖【HuTool工具包 redis】
  3. application.properties配置redis连接信息 4.发送请求 发送验证码

代码实现

  1. uniCloud云函数的封装【模板和签名的配置:基础配置 (dcloud.net.cn)
'use strict';
exports.main = async (event, context) => {
	
	//发送短信需要传的参数  这里主要是给过期时间和用途设置了默认值
	let action = '注册'			        //用途
	let phone = ''					//手机号
	let code = ''					//验证码
        let expMinute = '10'	    		        //过期时间
  	
	//get请求 获取参数
	if(event.queryStringParameters){
		action = event.queryStringParameters.action
		phone = event.queryStringParameters.phone
		code = event.queryStringParameters.code
		expMinute = event.queryStringParameters.expMinute
		
	}
	
	//post请求 获取参数 需要传 json格式的数据这里才能获取到这里直接解析请求体
	if(event.body){
		let data = JSON.parse(event.body)
		action = data.action
		phone = data.phone
		code = data.code
		expMinute = data.expMinute
	}
	
	const res = await uniCloud.sendSms({
		smsKey:'eb64a9a73877d5f',//smsKey 这两个key没有给全 所以不能直接用谢谢
		smsSecret:'d59c819764a',//smsSecret
		phone:phone,				//手机号
		templateId:'10352',		       //模板id
		data:{					//发送验证码 要传的参数
			name:'王恒润',								
			code:code,			//验证码
			action:action,			//验证码的用途解释说明
			expMinute:expMinute		//过期时间
		},
	})
	//返回数据
	return res
};
  1. maven引入依赖
<!-- hutool 工具包   封装了有很多工具类 这里主要用来发送http 请求 请求云函数    -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.13</version>
</dependency>
<!-- redis  我这里版本号在父项目中定义了 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

3.application.properties【这里不需要数据库所以没有配置】

# 服务端口
server.port=8206
# 服务名
spring.application.name=service-msm

#redis连接的配置信息 一般只需要配置这四个属性的值
spring.redis.host=192.168.6.100
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000

spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
#最小空闲


#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/ssm/mapper/xml/*.xml

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#云函数发送验证码的地址 云函数的地址 这是我自己封装的云函数
unicloud.url=https://29eebefd-7e53-4131-9b94-422631ce24c6.bspapp.com/http/smsPhoneCode

4.service层的实现

/**
 * uniCloud云函数 发送短信
 * @param phone     手机号
 * @param map     参数 键值对集合
 * @return
 */
@Override
public boolean sendUniCloud(String phone, Map<String, Object> map) {

    //手机号不能为空
    if(StringUtils.isEmpty(phone)) return false;

    //开始请求接口 参数:手机号 验证码
    map.put("phone",phone);
    //看到没 直接用HuTool包里面的工具类发送请求 直接写请求地址和参数
    //剩下的 code action 等参数让我在controller层封装了 这样有点不好 但是我现在懒的改
    String res = HttpUtil.get(uniCloudUrl, map);

    //将返回的 json字符串 变更成 Map<String,Object> 类型的数据
    JSONObject json = JSONObject.parseObject(res);
    Map<String,Object> result = json;
    System.out.println("发送验证码返回的数据 = " + res);

    return (boolean) result.get("success");
}

5.controller层实现

@GetMapping("/send/code/{phone}")
public R sendCode(@PathVariable String phone){

    //首先看缓存里面的验证码是否已存在 如果已存在直接将验证码返回
    String code = redisTemplate.opsForValue().get(phone);
    if(!StringUtils.isEmpty(code)) return R.ok();

    //如果redis没有验证码 开始生成
    code = RandomUtil.randomNumbers(6);
    Map<String,Object> map = new HashMap<>();
    map.put("code",code);
    //设置发送验证码的作用说明和过期时间
    map.put("action","王恒润实验发送验证码");
    //过期时间 单位是分钟
    map.put("expMinute",10);

    //开始发送短信
    boolean isSend = ssmService.sendUniCloud(phone, map);

    //判断发送失败 返回失败
    if(!isSend) return R.error().message("短信发送失败");

    //发送成功保存验证码 并返回成功 同时可以设置过期时间
    redisTemplate.opsForValue().set(phone,code,10,TimeUnit.MINUTES);
    return R.ok();
}