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

开通阿里云短信服务

阿里云官网

创建API的Key

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

创建成功

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

配置maven依赖

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

在配置类中新建一个AccessKey类

java 复制代码
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";
}

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

java 复制代码
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中用于账户提交注册的时候进行验证

java 复制代码
 /*
    * 验证码获取,用于账户注册及账户密码重置
    * 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部分代码

javascript 复制代码
<!--引用第三方插件(消息通知插件)-->
<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部分
javascript 复制代码
<!--引用第三方插件(消息通知插件)-->
<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代码

java 复制代码
    /*
    * 账户注册
    * 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结合阿里云实现短信验证码的完整代码,也不能说这篇文章很详细吧,自我感觉能够帮助有需要的伙伴,如果觉得改文章对你有用,可以评论一波哈,当然如果有不足之处,恳请各位在评论区指正,这样更方便他人能够发现并及时更改。上面我用的是注册账户的方法,登录或者密码找回实现的思路基本上是一样的,所以这里就没有呈现了。
相关推荐
ketil272 小时前
Ubuntu 安装 redis
redis
狂放不羁霸2 小时前
idea | 搭建 SpringBoot 项目之配置 Maven
spring boot·maven·intellij-idea
计算机学长felix3 小时前
基于SpringBoot的“校园交友网站”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·毕业设计·交友
码农派大星。3 小时前
Spring Boot 配置文件
java·spring boot·后端
王佑辉3 小时前
【redis】redis缓存和数据库保证一致性的方案
redis·面试
江深竹静,一苇以航3 小时前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
Karoku0664 小时前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
豪宇刘4 小时前
SpringBoot+Shiro权限管理
java·spring boot·spring
gorgor在码农4 小时前
Redis 热key总结
java·redis·热key
划水小将军4 小时前
阿里云函数计算GBK编码
阿里云·云计算