Java利用Redis实现短信验证码功能

1 篇文章 0 订阅
1 篇文章 0 订阅

本文将详情介绍从Redis+阿里云注册短信服务到后端调用等过程。

这个功能比较实用的地方就是注册用户的时候,防止一个用户多个账户注册,因为手机号毕竟有限

短信服务

首先,打开你的阿里云

在这里插入图片描述

话不多说,第一步,先充钱
阿里云短信一条默认为0.045元,发短信前提是你账户余额足够,我这里充了10块,勉强够支撑200条短信。
然后我们从阿里云找到短信服务并开通

在这里插入图片描述

开通之后,接下来是阿里云短信服务的主界面,点击左边的国内消息,可以看到我这里已经有一条是成功的。

在这里插入图片描述

接着我们点击右上角添加签名

在这里插入图片描述

可以看见有签名、适用场景、申请说明
签名这个地方我填的魔咒,所以接收验证码后的效果就是【魔咒】
也就是签名填的是验证码前面那个公司或者个人的品牌名称
适用场景这里填验证码
申请说明尽量填一些业务方面的,通过成功率高,我也是申请了3次才过

这里个人建议:

  • 签名先申请成功,再去申请模板。因为我个人就是,模板申请了三次都失败,签名第三次成功了,话说也是挺有意思,我这边是签名申请成功后,模板还等了好长时间才有结果,给我返回了个失败,然后我直接再次申请,申请说明我写了:我签名都通过了
  • 然后直接这次申请就成功了,所以签名你要是成功了模板会很容易。
接下来便到了模板申请,大家也可以看见我已经有一个模板

在这里插入图片描述

点击右上角模板申请

在这里插入图片描述

这里模板类型填验证码,模板名称可以随便填,当然建议正式点,通过申请概率会大。
模板内容呢,就是:

您的验证码为:${code},该验证码 5 分钟内有效,请勿泄露于他人。

申请内容也写的正式点,不然比较难通过。
这里说一下这个短信签名和模板的这个用处
先举个例子,我网站发送注册验证码的一条例子是:先举个例子,我网站发送注册验证码的一条例子是:

【魔咒】您的验证码为:1052,该验证码 5 分钟内有效,请勿泄露于他人。

这里【魔咒】就是签名名称
后面的

您的验证码为:1052,该验证码 5 分钟内有效,请勿泄露于他人。

就是模板内容,中间的验证码则是用${code}
好了,看到这里,大家应该两个都申请成功了

记住模板管理下面那个模板Code码,后面会用到

下一步,就要去获得大家专属的AccessKey码
点击右上角头像可以找到

在这里插入图片描述

进去之后会弹出这个界面,点击开始使用子用户AccessKey

在这里插入图片描述

接着从左边人员管理中进入用户组

在这里插入图片描述

点击创建用户组,创建一个用户组
创建完用户组之后点击左边菜单栏的用户,并创建用户

在这里插入图片描述

创建用户的时候注意,编程访问勾选上

在这里插入图片描述

接着从左边菜单栏进入用户组,点击用户组右边的添加权限

在这里插入图片描述

在添加权限页面,授权应用范围选择整个云账号
被授权主体就是当前用户组
选择系统策略,然后输入sms,选中第一个管理短信服务,添加到右边点确定

在这里插入图片描述

完成之后,在用户组界面点击添加组成员

在这里插入图片描述

如下为添加用户组成员界面,将刚才新建的用户添加到当前用户组当中。

在这里插入图片描述

最后点击你创建的用户,到用户详情页面,下面有个用户AccessKey,点击创建AccessKey,新建一个

这里注意,新建的时候会给你一个id和密码,一定要妥善记录好。尤其是密码,关闭这个页面之后就不会在显示了。

这个id和密码一定要保护好。

在这里插入图片描述

下一步就要在服务器上操作一些东西了。
我的服务器是阿里云简单搞的学生机
Redis的安装与操作便不再叙述了,大家要是有问题可以私聊我

这里总结几点Redis安装时可能会遇到的问题

  • Redis启动时要确保确认调用了你修改后的配置文件。
  • 我的服务器是阿里云的,所以注意阿里云服务器中的端口是否开放。没有开放的话要去安全组开放
接下来就是idea,后台这边的代码,大家可以到阿里云短信服务中的快速学习复制一份demo,也可以从我下面复制
需要注意的是,阿里云有的服务器可能会报错,我这边用的北京一个节点一直报错,,后面发现换了个节点就可以了
以下为代码,先上代码,代码下面给大家讲解一下部分代码

首先是Controller


import com.alibaba.fastjson.JSON;
import com.aliyuncs.utils.StringUtils;
import com.mozhoublog.service.SendSms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@CrossOrigin    //跨域支持
public class SmsApiController {

    @Autowired
    private SendSms sendSms;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @ResponseBody
    @GetMapping("/SendSms/{telephone}")
    public String code(@PathVariable("telephone") String telephone) throws Exception{
        //从Redis中获取手机号对应验证码
        String code = redisTemplate.opsForValue().get(telephone);
        //如果获取的验证码不为空,说明已经存在,至于这里我为什么使用Map后面会解释。
		if(!StringUtils.isEmpty(code)){
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("message","验证码已存在,还没有过期");
			//用Fastjson转为json返回
            return JSON.toJSONString(map);
        }
        //到了这里说明手机号获得的验证码为空,生成验证码并存储到Redis中
        HashMap<String,Object> param = new HashMap<>();
        code = String.valueOf((int)(Math.random()*9999)+100);
        param.put("code",code);
		//调用发送验证码方法,将发送的手机号,短信模板,以及验证码传入
        boolean isSend = sendSms.send(telephone, 短信模板Code, param);
		//如果发送成功,则将手机号和验证码存入Redis,设置为2分钟后过期
        if(isSend){
            redisTemplate.opsForValue().set(telephone,code,2, TimeUnit.MINUTES);
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("message","验证码发送成功!两分钟内有效");
            return JSON.toJSONString(map);
        }else{
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("message","验证码发送失败!未知错误!请联系管理员!");
            return JSON.toJSONString(map);
        }
    }
}

接下来是接口

import java.util.Map;

public interface SendSms {
    public boolean send(String phoneNum, String templateCode, Map<String,Object> code) throws Exception;
}

接口实现类

import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.models.*;
import com.aliyun.teaopenapi.models.*;
import org.springframework.stereotype.Service;

@Service
public class SendSmsImpl implements SendSms {

    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }
    
    public boolean send(String phoneNum, String templateCode, java.util.Map<String, Object> code) throws Exception{
	//下面将你获得的AccessKey ID和AccessKey Secret填入
        com.aliyun.dysmsapi20170525.Client client = SendSmsImpl.createClient("AccessKeyID", "AccessKeySecret");
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(phoneNum)
                .setSignName("这里填签名名称")
                .setTemplateCode(templateCode)
                .setTemplateParam(JSONObject.toJSONString(code));
        //接收发送结果
		SendSmsResponse response = client.sendSms(sendSmsRequest);
        SendSmsResponseBody sendSmsResponseBody = response.getBody();
        System.out.println("发送请求码:"+sendSmsResponseBody.code+"\t发送情况:"+sendSmsResponseBody.message+"发送的手机号码:"+phoneNum);
        //如果发送成功返回true,否则false
		if(sendSmsResponseBody.code.equals("OK")){
            return true;
        }else{
            return false;
        }
    }
}
这里说一下FastJson的问题,如果直接return “验证码已存在,还没有过期”;
你就会发现网页上返回信息中成了"验证码已存在,还没有过期",多出了双引号。
但是用HashMap转json不会出现这个问题

最后来相对应的pom给大家参考

<dependencies>
         <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>dysmsapi20170525</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
</dependencies>
前端我使用的ajax进行请求发送,下面是我的部分源码
<body>
			<div>
				<input type="text" name="telephone" class="phone_number" placeholder="输入手机号码" autocomplete="off" id="telephone"/>
			</div>
			<div>
				<button id='getcode' name="getcode" class="send-tis">免费获取验证码</button>
			</div>
<script src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
	var waitTime = 120;
	document.getElementById("getcode").onclick = function() {
		send();
		time(this);
	}
	function send(){
		$.ajax({
			url:"SendSms/"+$("#telephone").val(),
			type:"get",
			success:function(msg){
				alert(JSON.parse(msg).message);
			}
		});
	}
	function time(ele) {
		if (waitTime == 0) {
			ele.disabled=false;
			ele.innerHTML = "免费获取验证码";
			waitTime = 120;// 恢复计时
		} else {
			ele.disabled=true;
			ele.innerHTML = waitTime + "秒后可以重新发送";
			waitTime--;
			setTimeout(function() {
				time(ele)// 关键处-定时循环调用
			}, 1000)
		}
	}
</script>
</body>

在Idea application.yml中记得配置Redis

spring:
	redis:
    host: 服务器地址
    port: 端口
    password: Redis密码
最后附上我的网页注册页面~

在这里插入图片描述

在这里插入图片描述

本教程到这里就结束了,如果还有什么疑问可以评论,我会尽力给大家提供帮助!感谢观看~

最后附上个人博客,欢迎留言与访问~

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔咒i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值