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

server/2024/12/22 20:43:26/

开通阿里云短信服务

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

创建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 {// 阿里云短信服务// accessKeyIdpublic static final String accessKeyId = "你自己的accessKeyId";// accessKeySecretpublic 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 Secretcom.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());//将状态存入sessionsession.setAttribute("status", status);// 将验证码存入sessionsession.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.ppmy.cn/server/26193.html

相关文章

2、​​​​​​​FreeCAD模块与核心架构总结

FreeCAD作为一个开源的3D建模软件&#xff0c;其内部架构由多个模块组成&#xff0c;这些模块共同协作以支持软件的各种功能。本总结将基于提供的参考文档&#xff0c;对FreeCAD的核心模块、架构特性以及启动过程进行翻译和详细阐述。 核心模块概览 FreeCAD的核心模块主要包括…

设计模式第二次测试 | 数据库连接池设计(原型模式、创建者模式、适配器模式)

需求中文如下&#xff1a;原本是英文&#xff0c;用百度翻译转换而来 我们需要设计一个工具&#xff0c;它负责创建一个与数据库软件MySQL的连接池。 连接池中有数百个连接可供客户端使用。 所有连接对象都有相同的内容&#xff0c;但它们是不同的对象。 连接对象的创建是资源密…

机器人系统结构不确定性

定义&#xff1a;结构不确定性指的是系统的结构特性存在的不确定性。这意味着系统的动力学特性可能受到非线性、时变、时滞、饱和等因素的影响&#xff0c;导致系统的结构模型具有一定的不确定性。影响&#xff1a;结构不确定性会使得控制器的设计更加困难&#xff0c;因为传统…

数据结构===栈

文章目录 栈的定义实现一个栈用数组实现栈用链表实现栈支持动态扩容的栈 栈的应用小结 栈的定义 栈是一种先进后出的数据结构。它的操作受限。 栈&#xff0c;是一种先进后出&#xff0c;或者后进先出的数据结构。跟数组和链表相比&#xff0c;有一定的限制性。毕竟&#xff0…

第72天:漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

案例一&#xff1a;某 APP-Web 扫描-常规&联动-Burp&Awvs&Xray Acunetix 一款商业的 Web 漏洞扫描程序&#xff0c;它可以检查 Web 应用程序中的漏洞&#xff0c;如 SQL 注入、跨站脚本攻击、身份验证页上的弱口令长度等。它拥有一个操作方便的图形用户界 面&#…

文献速递:深度学习医学影像心脏疾病检测与诊断---利用深度学习进行动态心脏PET的自动帧间患者运动校正

Title 题目 Automatic Inter-frame Patient Motion Correction for Dynamic Cardiac PET Using Deep Learning 利用深度学习进行动态心脏PET的自动帧间患者运动校正 01 文献速递介绍 OSITRON正电子发射断层扫描&#xff08;PET&#xff09;心肌灌注成像已被证明相较于其他…

avl excite python二次开发1--python解释器需用内置解释器aws_cmd

avl excite python二次开发1--python解释器需用内置解释器aws_cmd 1、python解释器问题1.1、用外置python解释器&#xff0c;import WSInterface会失败(WSInterface.pyd)1.2、用内置解释器aws_cmd运行py脚本1.3 用内置解释器aws_python执行脚本三级目录 1、python解释器问题 1…

Hotcoin Research | 市场洞察:2024年4月22日-28日

加密货币市场表现 本周内加密大盘整体呈现出复苏状态&#xff0c;在BTC减半后进入到震荡上行周期。BTC在$62000-66000徘徊&#xff0c;ETH在$3100-3300徘徊&#xff0c;随着港交所将于 4 月 30 日开始交易嘉实基金的比特币和以太坊现货 ETF&#xff0c;周末行情有一波小的拉升…