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结合阿里云实现短信验证码的完整代码,也不能说这篇文章很详细吧,自我感觉能够帮助有需要的伙伴,如果觉得改文章对你有用,可以评论一波哈,当然如果有不足之处,恳请各位在评论区指正,这样更方便他人能够发现并及时更改。上面我用的是注册账户的方法,登录或者密码找回实现的思路基本上是一样的,所以这里就没有呈现了。
相关推荐
我不想名字重复3 分钟前
redis缓存和数据库数据保持一致
数据库·redis·缓存
流星白龙2 小时前
【Redis】8.List列表
redis
NWU_白杨3 小时前
三种常用的数据存储技术
数据库·redis·mysql·sqlite
我叫黑大帅3 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
陈天伟教授3 小时前
华为云 阿里云 腾讯 WorkBuddy的工具对比
阿里云·华为云·云计算
正儿八经的少年4 小时前
redis 的大 key 和热 key 详解
数据库·redis·缓存
dkbnull4 小时前
Spring Boot请求处理组件对比详解
java·spring boot
不能只会打代码4 小时前
Day 011 — Spring 全家桶深度拆解
spring boot·mybatis·spring aop·spring mvc·spring ioc
X-⃢_⃢-X4 小时前
十、Redis之布隆过滤器
数据库·redis·缓存
吴声子夜歌5 小时前
MongoDB 4.x——SpringBoot框架整合
数据库·spring boot·mongodb