java手机短信验证,并存入redis中,验证码时效5分钟

news2024/11/15 14:43:56

目录

1、注册发送短信账号一个账号

2、打开虚拟机,将redis服务端打开

3、创建springboot工程,导入相关依赖

4、写yml配置

5、创建controller层,并创建controller类

6、创建service层,并创建service类

7、创建工具类,将发送短信的代码放入工具类

8、返回值工具类

9、写前端代码验证


结合第三方API和redis实现以下功能:

1:手机短信验证,每条验证码有效期为5分钟,

2:五分钟内如果该手机号再次获取验证码,则提示短信已发送,请XX分钟后(剩余过期时间)重新

获取

3:每个手机号每天最多只能发送3次,24小时后可发送次数重置

1、注册发送短信账号一个账号

网址:https://www.ihuyi.com/

注册送10条免费短信

 发送短信需要对接相关资源

2、打开虚拟机,将redis服务端打开

3、创建springboot工程,导入相关依赖

工程结构

 

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>

4、写yml配置

spring:
  redis:
    port: 6379  #端口号
    host: 192.168.138.129 #虚拟机IP地址
    password: 123456 #密码
    database: 0 #redis默认数据库
    timeout: 5000
  mvc:
    static-path-pattern: /**   #加载静态资源
  thymeleaf:
    cache: false  #关闭页面缓存
    mode: HTML    #模板模式
    suffix: .html #构建URL时附加到查看名称的后缀

5、创建controller层,并创建controller类

@Controller
public class CodeController {
    @Autowired
    private CodeService codeService;
    //访问8080直接进入index页面
    @GetMapping("/")
    public String index(){
        return "index";
    }

    /**
     * @description 获取验证码
     * @author 
     * @date 2023-02-13 15:25:02
     * @param phone
     * @return {@link String}
     */
    @PostMapping("/getPhone")
    @ResponseBody
    public String phone(String phone){
        //调用方法,发送手机验证码
        String result = codeService.getCode(phone);
        if (result != null){
            return result;
        }
        return JSON.toJSONString(new R("0","验证码发送失败,请重试!",null));
    }
    /**
     * @description 登录验证
     * @author 
     * @date 2023-02-13 15:25:18
     * @param phone
     * @param code
     * @return {@link String}
     */
    @GetMapping("/login.do")
    public String login(String phone,String code){
        boolean flag = codeService.checkCode(phone, code);
        // 判断是否相同
        if (flag){
            // 相同,通过,跳转页面
            return "login";
        }else {
            // 不同,不通过,返回原页面
            return "index";
        }
    }
}

6、创建service层,并创建service类

@Service
public class CodeService {
    /**
     * @description 获取验证码
     * @author 
     * @date 2023-02-13 14:10:27
     * @param
     * @return {@link String}
     */
    public String phoneCode(){
        return (int)((Math.random()*9+1)*100000)+"";
    }
    /**
     * @description 根据手机号获取验证码,并设置有效期
     * @author 
     * @date 2023-02-13 14:11:42
     * @param
     * @return {@link String}
     */
    public String getCode(String phone){
        //手机号对应的次数key
        String countKey = phone +"_count";
        //手机验证码的key
        String codeKey = phone + "_code";
        //获取手机号次数
        String phoneCount = RedisTools.get(countKey);
        if (phoneCount == null || "".equals(phoneCount)){
            //第一次获取验证码,存入redis
            RedisTools.setEx(countKey,"1",1, TimeUnit.DAYS);
        }else if (Integer.parseInt(phoneCount) <= 2){
            //获取验证码剩余时间
            Long timeRemaining = RedisTools.getExpire(codeKey);
            if (timeRemaining > 0){
                //转换为分钟
                long m = timeRemaining / 60;
                //转换为秒
                long s = timeRemaining % 60;

                return JSON.toJSONString(new R("0","短信已成功发送,请"+m+"分钟"+s+"秒后重新获取",null));
            }
            //获取验证码次数加一
            RedisTools.incrBy(countKey,1);
        }else {
            return JSON.toJSONString(new R("0","今日发送验证码的次数已达上限!",null));
        }
        //获取验证码
        String phoneCode = this.phoneCode();
        //发送验证码,获取返回结果
        String result = CodeTools.getCode(phone, code);
        //String result = "{\"code\":2,\"msg\":\"account或password不正确\",\"smsid\":\"0\"}";
        //如果结果为空则发送验证码失败
        if (result == null){
            return JSON.toJSONString(new R("0","验证码获取失败!",null));
        }else {
            //将验证码存入redis
            RedisTools.setEx(codeKey,phoneCode,5,TimeUnit.MINUTES);
        }
        // 将字符串类型的json数据转换为json对象
        JSONObject jsonObject = JSONObject.parseObject(result);
        // 从json对象中拿取code   code为2时返回为正常
        String code = jsonObject.get("code").toString();

        if (code.equals("2")){
            return JSON.toJSONString(new R("1","验证码已发送,请注意查看!",null));
        }else {
            return JSON.toJSONString(new R("0","验证码发送失败,请重试!",null));
        }
    }
    /**
     * @description 登录验证
     * @author 
     * @date 2023-02-13 14:38:15
     * @param phone
     * @param code
     * @return {@link boolean}
     */
    public boolean checkCode(String phone,String code){
        String phoneCode ="";
        try {
            phoneCode = RedisTools.get(phone + "_code");
        }catch (Exception e){
            e.printStackTrace();
        }
        //判断验证码是否正确
        boolean flag = phoneCode.equals(code);
        return flag;
    }
}

7、创建工具类,将发送短信的代码放入工具类

发送短信工具类

String account = ""--->查看用户名是登录用户中心->验证码短信->产品总览->APIID

String passwor = ""----> //查看密码请登录用户中心->验证码短信->产品总览->APIKEY

public class CodeTools {

    /**
     * @description 发送验证码
     * @author 
     * @date 2023-02-13 16:04:08
     * @param phone
     * @param mobile_code
     * @return {@link String}
     */
    public static String getCode(String phone,String mobile_code){

        String postUrl = "http://106.ihuyi.cn/webservice/sms.php?method=Submit";
        //int mobile_code = (int)((Math.random()*9+1)*100000); //获取随机数
        //查看用户名是登录用户中心->验证码短信->产品总览->APIID
        String account = "";
        //查看密码请登录用户中心->验证码短信->产品总览->APIKEY
        String password = "";
        // 设置短信内容
        String content = new String("您的验证码是:" + mobile_code + "。请不要把验证码泄露给其他人。");
        String line, result = "";
        try {
            // 创建URL对象
            URL url = new URL(postUrl);
            // 创建连接对象
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 同意输出//允许连接提交信息
            connection.setDoOutput(true);
            //网页提交方式“GET”、“POST”
            connection.setRequestMethod("POST");
            // 设置字符编码
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Connection", "Keep-Alive");
            StringBuffer sb = new StringBuffer();
            sb.append("account="+account);
            sb.append("&password="+password);
            sb.append("&mobile="+phone);
            sb.append("&content="+content);
            // 设置返回数据的数据格式为JSON
            sb.append("&format=json");
            // 以各种流的转换请求数据
            java.io.OutputStream os =  connection.getOutputStream();
            os.write(sb.toString().getBytes());
            os.close();
            // 读取请求数据的结果
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
            while ((line = in.readLine()) != null) {
                // 对数据进行拼接
                result += line + "\n";
            }
            in.close();
            System.out.println(result);

        } catch (IOException e) {
            e.printStackTrace(System.out);
            return null;
        }
        // 返回API的返回结果,为JSON,,,,有的可能为XML,,注意自己的设置
        return JSON.toJSONString(new R("1","验证码已发送,请注意查看!",null));
    }
}

8、返回值工具类

@Data
public class R<T>{

    private String code;
    private String msg;
    private T data;

    public R() {
    }

    public R(String code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    @Override
    public String toString() {
        return "R{" +
                "code='" + code + '\'' +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

deris工具类提连接

链接:https://pan.baidu.com/s/1CCDD496oIGdRfqAIx8OQ2Q?pwd=tewx 
提取码:tewx

9、写前端代码验证

登录页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/js/jquery-1.12.4.js"></script>
    <script src="/js/phone.js"></script>
</head>
<body>
    <form action="login.do" method="get">
        电话:<input type="text" id="phone" name="phone">
        <span id="sub">获取验证码</span>
        <span id="msg"></span>
        <br>
        获取验证码:<input type="text" id="code" name="code">
        <input type="submit" value="登录">
    </form>

</body>
</html>

js代码

$(function (){
    $("#sub").click(function () {
        let phone = $("#phone").val();
        $.ajax({
            "url": "getPhone",
            "type": "post",
            "data": "phone=" + phone,
            "dataType": "json",
            "success": function (result) {
                //调用方法
                var code = result.code
                var msg = result.msg
                if (code==="0"){
                    $("#msg").html(msg);
                }else if (code==="1"){
                    $("#msg").html(msg);
                }
            },
            "error": function () {
                alert("校验失败00!")
            }
        });
    })
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/343086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL——priority_queue

一、priority_queue介绍及使用 1.priority_queue文档介绍 &#xff08;1&#xff09;优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的。 &#xff08;2&#xff09;此上下文类似与堆&#xff0c;在堆中可以…

树与图中的dfs和bfs—— AcWing 846. 树的重心 AcWing 847. 图中点的层次

一、AcWing 846. 树的重心1.1题目1.2思路分析题意&#xff1a;什么是树的重心&#xff1f;树的重心是指&#xff0c;删除某个结点后剩下的最大连通子树的结点数目最小&#xff0c;如下图是根据样列生成的树&#xff0c;若删除结点1&#xff0c;则剩下三个子树最大的是中间那颗结…

C++的 new 和 delete

文章目录一、new 和 delete 的使用二、operator new 和 operator delete 函数三、new 和 delete 的实现原理四、申请空间和释放空间应配套使用五、定位 new 表达式六、malloc/free 和 new/delete 的区别C语言的动态内存管理函数(malloc、calloc、realloc、free) 虽然可以继续在…

Python for 循环语句

Python for 循环语句Python for循环可以遍历任何序列的项目&#xff0c;如一个列表或者一个字符串。语法&#xff1a;for循环的语法格式如下&#xff1a;for iterating_var in sequence:statements(s)流程图&#xff1a;实例&#xff1a;实例#!/usr/bin/python# -*- coding: UT…

Hudi-简介和编译安装

简介 简介 Apache Hudi&#xff08;Hadoop Upserts Delete and Incremental&#xff09;是下一代流数据湖平台。Apache Hudi将核心仓库和数据库功能直接引入数据湖。Hudi提供了表、事务、高效的upserts/delete、高级索引、流摄取服务、数据集群/压缩优化和并发&#xff0c;同…

【yolov5】首次尝试目标检测利用prompt(完整操作流程)

1、打开prompt 2、切换到pytorch所在环境 conda activate freezing我的环境名是freezing&#xff0c;这里根据自己环境名去激活切换 3、进入到yolov5项目所在路径 激活完环境后立即执行指令当然是无效的&#xff0c;首先要进入到你的项目目录 首先看一下自己的项目在那个位…

https协议

文章目录对称加密方案非对称加密方案对称加密方案非对称加密方案对称加密方案非对称加密方案数字证书因为HTTP是明文传输&#xff0c;所以会很有可能产生中间人攻击&#xff08;获取并篡改传输在客户端及服务端的信息并不被人发觉&#xff09;&#xff0c;HTTPS加密应运而生。 …

【Java|golang】1234. 替换子串得到平衡字符串---双指针

有一个只含有 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符&#xff0c;且长度为 n 的字符串。 假如在该字符串中&#xff0c;这四个字符都恰好出现 n/4 次&#xff0c;那么它就是一个「平衡字符串」。 给你一个这样的字符串 s&#xff0c;请通过「替换一个子串」的方式&#xff0c;…

SpringBoot2知识点记录

SpringBoot2知识点记录1.SpringBoot2基础入门1.1 环境要求1.1.1 maven设置1.2 第一个程序 HelloWorld1.2.1 创建maven工程1.2.2 引入依赖1.2.3 创建主程序1.2.4 编写业务1.2.5 测试1.2.6 简化配置1.2.7 简化部署1.3 自动装配1.3.1 SpringBoot特点1.3.1.1 依赖管理1.3.1.2 自动装…

上班在群里摸鱼,逮到一个字节8年测试开发,聊过之后羞愧难当...

老话说的好&#xff0c;这人呐&#xff0c;一旦在某个领域鲜有敌手了&#xff0c;就会闲得某疼。前几天我在上班摸鱼刷群的时候认识了一位字节测试开发大佬&#xff0c;在字节工作了8年&#xff0c;因为本人天赋比较高&#xff0c;平时工作也兢兢业业&#xff0c;现在企业内有一…

【论文阅读】基于意图的网络(Intent-Based Networking,IBN)研究综述

IBN研究综述一、IBN体系结构1.1 体系结构&#xff1a;1.2 闭环流程&#xff1a;1.3 IBN的自动化程度(逐步向前演进)&#xff1a;二、IBN 的实现方式2.1 意图获取&#xff1a;2.1.1 YANG、NEMO2.1.2 Frenetic、NetKAT、LAI2.2 意图转译&#xff1a;2.2.1 iNDIRA系统2.2.2 基于模…

GIT命令操作大全

文章目录一、前言二、工作模块2.1 Workspace&#xff1a;工作区2.2 Index / Stage&#xff1a;暂存区2.3 Repository&#xff1a;本地仓库2.4Remote&#xff1a;远程仓库三、GIT基本配置四、GIT项目代码管理4.1 初始化git仓库4.2 提交到暂存区(stage)4.3 将暂存区的文件恢复到工…

解决HC-05/HC06等蓝牙模块的调试问题

解决HC-05/HC06等蓝牙模块的调试问题问题&#xff1a;1.无法使用USB转串口工具设置HC-05等蓝牙模块&#xff0c;具体问题是&#xff1a;发送AT指令&#xff0c;无回复&#xff1b;2.电脑如何连接HC-05模块&#xff0c;与模块通信&#xff08;具体场景&#xff1a;HC-05模块的串…

python学习之pyecharts库的使用总结

pyecharts官方文档&#xff1a;https://pyecharts.org//#/zh-cn/ 【1】Timeline 其是一个时间轴组件&#xff0c;如下图红框所示&#xff0c;当点击红色箭头指向的“播放”按钮时&#xff0c;会呈现动画形式展示每一年的数据变化。 data格式为DataFrame&#xff0c;数据如下图…

数据结构——TreeMap、TreeSet与HashMap、HashSet

目录 一、Map 1、定义 2、常用方法 3、注意 二、TreeMap 三、HashMap 1、定义 2、冲突定义 3、冲突避免方法——哈希函数设计 &#xff08;1&#xff09;、直接定制法(常用) &#xff08;2&#xff09;、除留余数法(常用) &#xff08;3&#xff09;、平方取中法 &…

kubectl命令控制远程k8s集群(Windows系统、Ubuntu系统、Centos系统)

文章目录1. 本地是linux2. 本地是Windows1. 本地是linux 安装kubectl命令 法一&#xff1a;从master的/usr/bin目录下拷贝kubectl文件到本机/usr/bin目录下法二&#xff1a;GitHub下载kubectl文件 在家目录下创建.kube目录config文件 法一&#xff1a;将master上对应用户的~/.…

binlog、redolog、undolog

目录 一、binlong 1、binlog介绍 作用 特点 2、日志格式 3、写入流程 二、redo log 1、redo log作用 2、redo log如何写入 3、怎么提交数据进行刷盘 4、奔溃恢复流程 三、undolog 一、binlong 1、binlog介绍 作用 binlog是 mysql server 层的一种二进制日志&…

GA-PEG-GA,Glutaric Acid-PEG-Glutaric Acid,戊二酸-聚乙二醇-戊二酸供应

英文名称&#xff1a;Glutaric Acid-PEG-Glutaric Acid&#xff0c;GA-PEG-GA 中文名称&#xff1a;戊二酸-聚乙二醇-戊二酸 GA-PEG-GA是一种线性双功能PEG羧酸试剂。PEG和羧基COOH之间存在C4酯键。PEG羧酸可用于与氨基反应&#xff0c;与NHS和DCC、EDC等肽偶联试剂反应。 P…

CUDA原子操作|参加CUDA线上训练营

什么是原子操作 CUDA的原子操作可以理解为对一个Global memory或Shared memory中变 “读取-修改-写入” 这三个操作的一个最小单位的执行过程&#xff0c;在它执量进行行过程中&#xff0c;不允许其他并行线程对该变量进行读取和写入的操作。 基于这个机制&#xff0c;原子操…

实测2023款哪吒U-II,智驾功能对女司机很友好

最近&#xff0c;我们受邀试驾了2023款哪吒U-II。这是一款A级新能源SUV&#xff0c;是哪吒U的改款车型。哪吒U系列自2020年3月上市到2023年1月&#xff0c;累计销售数量达76688台&#xff0c;也因此被称为15万级智能天花板。2023款哪吒U-II的一大亮点是&#xff1a;针对以往哪吒…