SpringBoot+阿里云实现验证码登录注册及重置密码

news2025/1/11 11:11:34

开通阿里云短信服务

阿里云官网
在这里插入图片描述

创建API的Key

在这里插入图片描述

可以使用手机号或者刷脸来进行创建Key

在这里插入图片描述

创建成功

在这里插入图片描述

开通完成以后接下来实现代码请求阶段

配置maven依赖

 <!-- 阿里云 oss 短信 依赖-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>dysmsapi20170525</artifactId>
            <version>2.0.24</version>
        </dependency>

在配置类中新建一个AccessKey类

package com.example.erp_project.config;

/**
 * @author Lolo don‘t feel
 * @create 2022-05-09 16:09
 * 阿里云短信服务
 */
public class AccessKey {
    // 阿里云短信服务
    // accessKeyId
    public static final String accessKeyId = "你自己的accessKeyId";
    // accessKeySecret
    public static final String accessKeySecret = "你自己的accessKeySecret";
    // 短信模板code 对应下图的,你自己的code即可
    //账户注册
    public static final String templateCode = "你自己创建的模板的code";
    //密码重置
    public static final String templateCode2 = "你自己创建的模板的code";
}

在这里插入图片描述

创建短信发送服务类(在工具类中创建)

package com.example.erp_project.util;

import com.aliyun.tea.TeaException;
import com.example.erp_project.config.AccessKey;

/**
 * @author Lolo don‘t feel
 * 短信验证码
 */
public class Sample {
    /**
     * 创建一个阿里云短信客户端的方法
     * 使用AK&SK初始化账号Client
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        // 创建一个配置对象,用于存储AccessKey ID和AccessKey Secret
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填,您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 设置请求的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        // 使用配置对象创建一个新的阿里云短信客户端并返回
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    /**
     * 发送验证码
     *
     * @param phone            电话
     * @param verificationCode 验证码
     */
    // 定义一个发送短信验证码的方法,参数为手机号、验证码和类型
    /*我这里设置的参数是三个参数,因为我定义了一个status来辨别发送的短信模板,
    *正常情况下是手机号和验证码两个参数,如果你的模板不一样也可以使用一个参数来辨别		该使用哪个模板
    */
    public static void sendingCode(String phone, String verificationCode, Integer status) {
        // 创建一个阿里云短信客户端对象
        com.aliyun.dysmsapi20170525.Client client = null;
        try {
            // 使用AccessKeyId和AccessKeySecret创建客户端
            //引用上方createClient方法创建客户端
            client = Sample.createClient(AccessKey.accessKeyId, AccessKey.accessKeySecret);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 创建一个发送短信请求对象,并设置签名、手机号和模板参数
        com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                // 设置签名名称
                .setSignName("暖意ERP")
                // 设置手机号
                .setPhoneNumbers(phone)
                // 设置模板参数验证码
                .setTemplateParam("{\"code\":\"" + verificationCode + "\"}");
		//注:如果你只设置了一个通用模板你就把sendSmsRequest.setTemplateCode(AccessKey.templateCode);从if中拿出来就可以了
        // 根据类型设置不同的模板代码
        if (status == 1) {
            //如果类型为1,则使用模板代码1注册模板
            sendSmsRequest.setTemplateCode(AccessKey.templateCode);
        } else if (status == 2) {
            //如果类型为2,则使用模板代码2重置密码模板
            sendSmsRequest.setTemplateCode(AccessKey.templateCode2);
        }

        // 创建一个运行时选项对象
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 使用客户端发送短信请求
            client.sendSmsWithOptions(sendSmsRequest, runtime);
        } catch (TeaException error) {
            // 处理TeaException异常
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            // 处理其他异常
            TeaException error = new TeaException(_error.getMessage(), _error);
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
    }

}

接下来就是在短信验证的时候进行验证了(loginController)

这里是账户注册的时候进行短信验证,我将结果保存到了session中用于账户提交注册的时候进行验证

 /*
    * 验证码获取,用于账户注册及账户密码重置
    * sendValidateCode
    * */
    @GetMapping("/sendValidateCode")
    public ResultUtil sendValidateCode(@RequestParam(value = "phone") String phone,
                                       @RequestParam(value = "status") Integer status, HttpSession session) {
        //测试手机号和验证码类型是否正确
        // System.out.println("手机号:"+phone);
        // System.out.println("验证码类型:"+status);
        // 判断手机号和验证码类型是否为空
        if (phone != null && status != null) {
            // 验证码
            String verificationCode = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
            // System.out.println("验证码:"+verificationCode);
            //验证码发送,调用短信发送工具类
            Sample.sendingCode(phone, verificationCode, status);
            // 将验证码和当前手机号存入session,在账户注册的时候进行校验操作
            session.setAttribute("phone", phone);
            //保存当前发送时间
            session.setAttribute("sendTime", new Date());
            //将状态存入session
            session.setAttribute("status", status);
            // 将验证码存入session
            session.setAttribute("verificationCode", verificationCode);
            // 返回成功信息
            return ResultUtil.ok(0, "验证码发送成功,请注意查收哦!");
        }
        // 返回失败信息
        return ResultUtil.error("验证码发送失败");
    }

获取验证码对应的js部分代码

<!--引用第三方插件(消息通知插件)-->
<script th:src="@{/dist/notify/notify.js}"></script>
<script>
    layui.use(['notify'], function () {
        var $ = layui.$;
        var form = layui.form;
        var layer = layui.layer;
        var util = layui.util;
        var notify = layui.notify;

        // 获取验证码进行验证
        $('#validate-get-vercode').on('click', function () {
            var isValid = form.validate('#reg-cellphone');  // 验证手机号进行主动触发
            //获取手机号
            var cellphone = $('#reg-cellphone').val();
            //console.log("注册手机号:"+cellphone);
            // 验证通过
            if (isValid) {
                //向后端发送验证码请求
                $.ajax({
                    type: 'GET',
                    url: "/auth/sendValidateCode",//实现验证
                    data: {"phone": cellphone, "status": 1},
                    success: function (d) { // 返回的RequestResult的json对象
                        if (d.code === 0) {
                            notify.info(d.msg, "vcenter", "shadow", false);

                            /*
                            * 实现获取验证码按钮倒计时的代码
                            */
                            
                            //禁用按钮不可再次点击,这里如果不设置就会一直点击倒计时会重复计时
                            document.getElementById('validate-get-vercode').disabled = true;
                            // 倒计时60s以后可再次点击
                            var count = 60;//定义时间
                            var countdown = setInterval(function () {
                                    if (count > 0) {
                                        //按钮文字倒计时信息提示
                                        document.getElementById('validate-get-vercode').innerText = count + 's后再次获取';
                                        //时间减
                                        count--;
                                    } else {
                                        //倒计时结束以后按钮文字提示显示
                                        document.getElementById('validate-get-vercode').innerText = '获取验证码';
                                        //取消按钮禁用,用于验证码过期以后进行再次获取
                                        document.getElementById('validate-get-vercode').disabled = false;
                                        clearInterval(countdown);
                                    }
                                },
                                1000);
                                //按钮倒计时结束



                        } else {
                            notify.error(d.msg, "vcenter", "shadow", false);
                        }
                    },
                })
            }
        });

    });
</script>

在这里插入图片描述

下面就是点击注册账户按钮实现账户注册操作的代码

js部分
<!--引用第三方插件(消息通知插件)-->
<script th:src="@{/dist/notify/notify.js}"></script>
<script>
    layui.use(['notify'], function () {
        var $ = layui.$;
        var form = layui.form;
        var layer = layui.layer;
        var util = layui.util;
        var notify = layui.notify;

        // 验证注册密码是否一致
        form.verify({
            // 确认密码
            confirmPassword: function (value, item) {
                var passwordValue = $('#password').val();
                if (value !== passwordValue) {
                    return '两次密码输入不一致';
                }
            }
        });
        // 提交账户注册事件
        form.on('submit(register)', function (data) {
            var field = data.field; // 获取表单字段值
            //验证码为6位
            if (!/^\d{6}$/.test(field.vercode)) {
                notify.warning('验证码必须为 6 位的数字', "vcenter", "shadow", false);
                return false;
            }
            //验证密码
            if (!/^[\S]{6,16}$/.test(field.password)) {
                notify.warning('密码必须为 6 到 16 位的非空字符', "vcenter", "shadow", false);
                return false;
            }
            // 是否勾选同意
            if (!field.agreement) {
                notify.info('您必须勾选同意服务条款才能注册账户', "vcenter", "shadow", false);
                return false;
            }
            // 获取表单信息将账户及密码传递到后断进行验证
            notify.loading("系统正在验证并注册新账户,请稍等", "vcenter", "shadow", false);
            setTimeout(function () {
                notify.destroyAll(); //先关闭loading
                $.ajax({
                    type: 'POST',
                    url: "/auth/register",//实现账户注册请求
                    data: {
                        "account": field.cellphone,   // 手机号
                        "vercode": field.vercode, // 验证码
                        "password": field.password, // 密码
                        "nickname": field.nickname // 昵称
                    },
                    success: function (d) { // 返回的RequestResult的json对象
                        if (d.code === 0) {
                            //账户注册成功
                            notify.success(d.msg, "vcenter", "shadow", false)
                        } else if (d.code === 1) {
                            //账户存在,或者验证码错误提示
                            notify.warning(d.msg, "vcenter", "shadow", false);
                        } else {
                            //账户注册失败
                            notify.error(d.msg, "vcenter", "shadow", false);
                        }
                    },
                }).done(function () {
                    setTimeout(function () {
                        parent.location.reload();//重载页面
                    }, 1500);
                });
            }, 3000);
            return false; // 阻止默认 form 跳转
        });
           });
</script>

接着再是controller代码

    /*
    * 账户注册
    * register
    * */
    @PostMapping("/register")
    public ResultUtil register(@RequestParam(value = "account") String account,
                               @RequestParam(value = "password") String password,
                               @RequestParam(value = "vercode") String vercode,
                               @RequestParam(value = "nickname") String nickname,HttpSession session) {
        //测试数据
        //System.out.println("账户:"+account+"密码:"+password+"验证码:"+vercode+"昵称:"+nickname);
        //从session中获取验证码
        String verificationCode = (String) session.getAttribute("verificationCode");
        //从session中获取手机号
        String phone = (String) session.getAttribute("phone");
        //获取session中的发送时间
        Date sendTime = (Date) session.getAttribute("sendTime");
        //从session中获取验证码类型
        Integer status = (Integer) session.getAttribute("status");
        //第一步判断,这里必须要status为1,否则就是验证码类型错误
        if (status != null && status == 1) {
            //如果session中没有发送时间,则验证码失效,这里如果不做判断会报错导致下面时间判断出错
            if (sendTime==null){
                return ResultUtil.warning(1,"验证码已失效,请重新获取验证码");
            }
            //判断如果现在时间大于发送时间5分钟,则验证码失效
            if (new Date().getTime() - sendTime.getTime() > 5 * 60 * 1000) {
                //清空session中的手机号
                session.removeAttribute("phone");
                //清空session中的验证码
                session.removeAttribute("verificationCode");
                //清空session中的发送时间
                session.removeAttribute("sendTime");
                //验证码失效
                return ResultUtil.warning(1, "验证码已失效,请重新获取验证码");
            }
            //判断当前的手机号和验证码是否与session中的手机号和验证码是否一致
            if (phone.equals(account) && verificationCode.equals(vercode)) {
                //根据账户查询用户信息,如果用户信息为空,则进行注册操作
                UserEntity user = userService.getUserByAccount(account);
                if (user == null) {
                    // 密码加密
                    String encrypt = MD5Util.encrypt(password);
                    // 创建用户实体
                    UserEntity userEntity = new UserEntity();
                    // 设置用户信息
                    userEntity.setAccount(account);
                    // 设置密码
                    userEntity.setPassword(encrypt);
                    //设置昵称
                    userEntity.setNickname(nickname);
                    //设置状态
                    userEntity.setStatus(1);
                    //设置角色
                    userEntity.setRoleId(2);
                    //进行注册
                    userService.registerAccount(userEntity);
                    //返回成功信息
                    return ResultUtil.ok(0, "账户注册成功!");
                }
                return ResultUtil.warning(1,"该账户已存在,请勿重复注册");
            }
            return ResultUtil.warning(1, "请输入正确的手机号或验证码");
        }
        return ResultUtil.error( "该验证码不适用于当前操作!");
    }
ok以上就是SpringBoot结合阿里云实现短信验证码的完整代码,也不能说这篇文章很详细吧,自我感觉能够帮助有需要的伙伴,如果觉得改文章对你有用,可以评论一波哈,当然如果有不足之处,恳请各位在评论区指正,这样更方便他人能够发现并及时更改。上面我用的是注册账户的方法,登录或者密码找回实现的思路基本上是一样的,所以这里就没有呈现了。

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

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

相关文章

Electron+Vue3+Vite+ElectronForge整合 - 一键启动两个服务 一键打包两个服务

说明 本文介绍一下 Electron Vue3 Vite Electron Forge 的高级整合操作。vue3 : 使用 TS 的语法开发&#xff1b; Electron : 使用 JS 的语法开发。本文将从项目初始化开始&#xff0c;一步一步的完成项目的启动、打包全流程的介绍。实现的效果是 &#xff1a; 1、一个正常…

Notes for the missing semester. Useful and basic knowledge about Linux.

The Shell Contents The first course is to introduce some simple commands. I’ll list some commands that I’m not familiar with: # --silent means dont give log info, # --head means we only want the http head. curl --head --silent bing.com.cn# cut --deli…

如何选择适合的美国站群服务器:经济实惠而可靠的选择

如何选择适合的美国站群服务器&#xff1a;经济实惠而可靠的选择 在今天的数字化时代&#xff0c;选择适合的服务器对于个人网站或企业来说至关重要。一台性能稳定、价格实惠的美国站群服务器能够为您的网站提供所需的支持&#xff0c;但在选择之前&#xff0c;有一些关键因素…

基于模糊PI控制算法的龙格库塔CSTR模型控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于模糊PI控制算法的龙格库塔CSTR模型控制系统simulink建模与仿真。基于模糊PI控制算法的龙格-库塔&#xff08;Runge-Kutta, RK&#xff09;连续搅拌釜反应器&#xff08;Co…

Allegro如何给铜皮赋信号

如何给铜皮赋信号 第一步&#xff1a;选中铜皮 第二步&#xff1a;鼠标点击右键&#xff0c;点击“Assign Net”&#xff0c;然后点击对应的Net信号就可以了

案例分享:使用RabbitMQ消息队列和Redis缓存优化Spring Boot秒杀功能

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c…

设计模式(十一):外观模式

设计模式&#xff08;十一&#xff09;&#xff1a;外观模式 1. 外观模式的介绍2. 外观模式的类图3. 外观模式的实现3.1 创建一个接口3.2 创建接口的实现3.3 创建一个外观类3.4 测试 1. 外观模式的介绍 外观模式&#xff08;Facade Pattern&#xff09;属于结构型模式&#xf…

智能科技的飞跃:LLAMA3引领的人工智能新时代

大家好&#xff01;相信大家对于AI&#xff08;人工智能&#xff09;的发展已经有了一定的了解&#xff0c;但你是否意识到&#xff0c;到了2024年&#xff0c;AI已经变得如此强大和普及&#xff0c;带来了我们从未想象过的便利和创新呢&#xff1f;让我们一起来看看AI在这个时…

【javaWeb项目】基于网页形式,通过浏览器访问的java应用程序,就称为javaweb程序

JavaWeb前端 第一章 1、javaWeb是什么 //基于网页形式&#xff0c;通过浏览器访问的java应用程序&#xff0c;就称为javaweb程序2、web程序的分类 //1、静态web程序特点&#xff1a;网页上的内容是固定不变的&#xff0c;不能动态加载&#xff0c;例如web前端//2、动态web程序…

chrome和drive安装包路径

Chrome for Testing availability (googlechromelabs.github.io) 下载Stable下面的包哈

深入剖析Tomcat(五) 剖析Servlet容器并实现一个简易Context与Wrapper容器

上一章介绍了Tomcat的默认连接器&#xff0c;后续程序都会使用默认连接器。前面有讲过Catalina容器的两大块内容就是连接器与Servlet容器。不同于第二章的自定义丐版Servlet容器&#xff0c;这一章就来探讨下Catalina中的真正的Servlet容器究竟长啥样。 四种容器 在Catalina中…

VTK —— 二、教程六 - 为模型加入3D微件(按下i键隐藏或显示)(附完整源码)

代码效果 本代码编译运行均在如下链接文章生成的库执行成功&#xff0c;若无VTK库则请先参考如下链接编译vtk源码&#xff1a; VTK —— 一、Windows10下编译VTK源码&#xff0c;并用Vs2017代码测试&#xff08;附编译流程、附编译好的库、vtk测试源码&#xff09; 教程描述 本…

数据挖掘之基于Lightgbm等多模型消融实验的信用欺诈检测实现

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 在当前的金融环境中&#xff0c;信用欺诈行为日益增多&#xff0c;给金融机构和消费者带来了巨大的损…

RS0108YQ20功能和参数介绍及高速数据传输中的优势

RS0108YQ20功能和参数介绍及高速数据传输中的优势-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 RS0108YQ20是一款电平转换器&#xff0c;也称为电平移位器&#xff0c;它的主要功能是在不同的电源电压或逻辑电平之间提供双向信号转换。以下是RS0108YQ20的一些关键参数和功能特…

使用UmcFramework和unimrcpclient.xml连接多个SIP设置的配置指南及C代码示例

使用UmcFramework和unimrcpclient.xml连接多个SIP设置的配置指南及C代码示例 引言1. UniMRCP和UmcFramework简介2. 准备工作3. unimrcpclient.xml配置文件3.1 定义SIP设置3.2 定义MRCP会话配置文件 4. C代码示例5. 测试和验证6. 故障排查7. 结论8. 参考文献 引言 在多媒体通信…

Django后台项目开发实战二

我们的需求是开发职位管理系统 三个功能&#xff1a; 管理员发布职位候选人能浏览职位用户能投递职位 第二阶段 创建应用 jobs&#xff0c;实现职位数据的建模 python manage.py startapp jobs 然后再 setting .py 注册应用&#xff0c;只需添加应用名称到最后一行 INST…

单片机排队叫号系统Proteus仿真程序 有取号键和叫号键以及重复叫号键 有注释

目录 1、前言 ​ 2、程序 资料下载地址&#xff1a;单片机排队叫号系统Proteus仿真程序 有取号键和叫号键以及重复叫号键 有注释 1、前言 系统组成&#xff1a;STC89C52RCLcd1602蜂鸣器按键 具体介绍&#xff1a; Lcd1602排队叫号系统&#xff0c;有取号显示窗和叫号显示窗…

Ubuntu 16.04下Firefox版本更新

最近要使用Odoo进行项目管理&#xff0c;Odoo17以上版本对浏览器版本要求较高&#xff0c;如果没有新版本下的函数&#xff0c;将无法运行。而Ubuntu16.04下自带的firefox不满足版本要求&#xff0c;因而需要手动下载安装。 查看当前系统版本apt-get能下载的firefox版本 apt-c…

排序算法大总结

引言 排序算法&#xff08;sorting algorithm&#xff09;是用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用&#xff0c;因为有序数据通常能够被更高效地查找、分析和处理。 如图 1-1 所示&#xff0c;排序算法中的数据类型可以是整数、浮点数、字符或字符串等…

ubuntu下anaconda虚拟环境开机自启动

&#xff08;1&#xff09; 要在Ubuntu系统中使Anaconda环境下的Python脚本在开机时自启动&#xff0c;可以通过创建一个systemd服务单元来实现。以下是步骤和示例代码&#xff1a; 创建一个新的systemd服务文件。 打开文本编辑器&#xff0c;创建一个新的服务文件。例如&…