若依微服务集成手机短信验证码登陆

为了响应公司项目的特定需求,增强用户体验与安全性,集成手机短信验证码登录功能至基于若依微服务框架开发的应用中,故创作此篇为未来类似项目提供了可借鉴的实施范例。

文章目录

    • 1.设计思路
    • 2.发送手机验证码接口
    • 3.发送手机验证码接口
    • 4.post请求工具类
    • 5.登录校验接口
    • 6.nacos配置请求白名单
    • 7.nacos配置短信服务密钥
    • 8.获取手机验证码测试

1.设计思路

大致可分为这几个阶段:生成验证码并存储至redis缓存中,发送验证码,用户登陆验证

2.发送手机验证码接口

/*** 发送手机验证码* @param phoneNumber* @return*/@GetMapping("/code/{phoneNumber}")public AjaxResult sendCode(@PathVariable String phoneNumber) {// 从Redis中获取最后一次发送验证码的时间戳String lastSentTimeStr = redisService.getCacheObject(phoneNumber + "lastSendTime");if (lastSentTimeStr != null) {long lastSentTime = Long.parseLong(lastSentTimeStr);// 计算当前时间与上次发送时间的时间差long timeDiff = Duration.between(Instant.ofEpochMilli(lastSentTime), Instant.now()).toMillis();// 如果时间差小于60秒,则返回错误if (timeDiff < 60_000) {return AjaxResult.error("您的短信发送过于频繁,请60s后再试!");}}//生成6位随机验证码Random randObj = new Random();String smsCode = Integer.toString(100000 + randObj.nextInt(900000));//发送短信boolean isSend = sysSmsApiService.send(phoneNumber,smsCode);if(!isSend){return AjaxResult.error("短信发送失败!");}// 更新Redis中该手机号最后发送验证码的时间戳redisService.setCacheObject(phoneNumber + "lastSendTime", String.valueOf(Instant.now().toEpochMilli()), 60L, TimeUnit.SECONDS);//将验证码保存至redis缓存中,设置有限期为5分钟redisService.setCacheObject(phoneNumber,smsCode,5L,TimeUnit.MINUTES);return AjaxResult.success();}

3.发送手机验证码接口

@Value("${tax.url}")private String url;@Value("${tax.key}")private String key;@Value("${tax.vipara}")private String vipara;/*** 发送短信* @param phoneNumber* @param smsCode* @return*/@Overridepublic boolean send(String phoneNumber, String smsCode) {try {SendtoVo sendtoVo = new SendtoVo();sendtoVo.setSjhm(phoneNumber);String content = "短信模板";   //自己根据业务需求编写sendtoVo.setContent(content);HashMap<Object, Object> map = new HashMap<>();map.put("*******", "********");map.put("data", JSON.toJSONString(sendtoVo));Map result = doPostUtils.doPost(url, map, key, vipara);    //此处传入小程序配置参数
//            System.out.println("短信发送返回结果======================:" + result);if (result != null) {return true;} else {return false;}} catch (Exception e) {e.printStackTrace();}return false;}

4.post请求工具类

    /*** 向指定 URL 发送POST方法的请求** @param httpUrl*            发送请求的 URL* @param map*  请求参数是json*  @param key* key* @return 所代表远程资源的响应结果*/public static Map doPost(String httpUrl, Map map,String key,String vipara) {log.info(JSON.toJSONString(map));map.put("data",Base64Utils.JsonToBase64((String) map.get("data")));String jsonString = JSON.toJSONString(map);String Aesdata = AesUtils.encrypt(jsonString, key,vipara);HttpURLConnection connection = null;InputStream is = null;OutputStream os = null;BufferedReader br = null;String result = null;try {URL url = new URL(httpUrl);// 通过远程url连接对象打开连接connection = (HttpURLConnection) url.openConnection();// 设置连接请求方式connection.setRequestMethod("POST");// 设置连接主机服务器超时时间:15000毫秒connection.setConnectTimeout(15000);// 设置读取主机服务器返回数据超时时间:60000毫秒connection.setReadTimeout(60000);// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为trueconnection.setDoOutput(true);// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无connection.setDoInput(true);// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。connection.setRequestProperty("Content-Type", "application/json");// 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0// connection.setRequestProperty("Authorization", "Bearer// da3efcbf-0845-4fe3-8aba-ee040be542c0");// 通过连接对象获取一个输出流os = connection.getOutputStream();// 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的os.write(Aesdata.getBytes());// 通过连接对象获取一个输入流,向远程读取if (connection.getResponseCode() == 200) {is = connection.getInputStream();// 对输入流对象进行包装:charset根据工作项目组的要求来设置br = new BufferedReader(new InputStreamReader(is, "UTF-8"));StringBuffer sbf = new StringBuffer();String temp = null;// 循环遍历一行一行读取数据while ((temp = br.readLine()) != null) {sbf.append(temp);sbf.append("\r\n");}result = sbf.toString();}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {// 关闭资源if (null != br) {try {br.close();} catch (IOException e) {e.printStackTrace();}}if (null != os) {try {os.close();} catch (IOException e) {e.printStackTrace();}}if (null != is) {try {is.close();} catch (IOException e) {e.printStackTrace();}}// 断开与远程地址url的连接connection.disconnect();}String result1 = AesUtils.decrypt(result, key,vipara);Map map1 = JSON.parseObject(result1, Map.class);String data2 = (String) map1.get("data");if ("0".equals(map1.get("code").toString())){String s = Base64Utils.Base64ToJson(data2);map1.put("data",s);log.info(map1.toString());return map1;}return null;}

5.登录校验接口

	/*** 手机短信登录* @param phoneNumber* @param smsCode* @return*/public LoginUser smsLogin(String phoneNumber, String smsCode) {// 手机号或验证码为空 错误if (StringUtils.isAnyEmpty(phoneNumber, smsCode)) {recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, "手机号/验证码必须填写");throw new ServiceException("手机号/验证码必须填写");}// 手机号输入错误if (phoneNumber.length() != UserConstants.PHONE_NUMBER_LENGTH){recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, "手机号输入错误");throw new ServiceException("手机号输入错误,请检查");}// 验证码输入错误if (smsCode.length() != UserConstants.CODE_LENGTH){recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, "验证码输入错误");throw new ServiceException("验证码输入错误,请检查");}//通过手机号查询用户信息R<LoginUser> userResult = remoteUserService.getUserInfoByPhoneNumber(phoneNumber, SecurityConstants.INNER);if (R.FAIL == userResult.getCode()) {throw new ServiceException(userResult.getMsg());}if (StringUtils.isNull(userResult.getData())) {recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, "登录手机号不存在");throw new ServiceException("登录手机号:" + phoneNumber + " 不存在");}LoginUser userInfo = userResult.getData();//在redis中获取验证码String cacheCode = redisService.getCacheObject(phoneNumber);if(cacheCode == null || ObjectUtils.isEmpty(cacheCode)) {recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, "验证码不存在或已过期");throw new ServiceException("验证码不存在或已过期");}if(cacheCode.equals(smsCode)){//验证码正确,可删除验证码redisService.deleteObject(phoneNumber);recordLogininfor(phoneNumber, Constants.LOGIN_SUCCESS, "登录成功");} else {recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, "验证码输入有误");throw new ServiceException("验证码输入有误");}return userInfo;}

6.nacos配置请求白名单

在这里插入图片描述

7.nacos配置短信服务密钥

在这里插入图片描述

8.获取手机验证码测试

在这里插入图片描述
9.用户登录测试
在这里插入图片描述

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

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

相关文章

云动态摘要 2024-07-16

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 数据库上云优选 阿里云 2024-07-04 RDS、PolarDB、Redis、MongoDB 全系产品新用户低至首年6折起&#xff01; [免费体验]智能助手ChatBI上线 腾讯云 2024-07-02 基于混元大模型打造&…

开放式耳机性价比推荐!免费总结功课给你参考!

在选择适合自己的耳机时&#xff0c;确实需要考虑多方面的因素&#xff0c;包括音质、舒适度、佩戴方式、续航能力、防水性能等。开放式耳机因其独特的设计&#xff0c;不仅能够提供良好的音质体验&#xff0c;还能让你在享受音乐的同时&#xff0c;保持对周围环境的感知&#…

AI数字人直播源码解析:灰豚私有化部署背后的技术分析

随着AI数字人技术的应用潜力不断显现&#xff0c;与AI数字人相关的多个项目逐渐成为创业者们的重点关注对象&#xff0c;作为当前AI数字人典型应用场景之一的数字人直播意向人数更是屡创新高&#xff0c;AI数字人直播源码部署的热度也因此不断飙升&#xff0c;与各大数字人源码…

python-区间内的真素数(赛氪OJ)

[题目描述] 找出正整数 M 和 N 之间&#xff08;N 不小于 M&#xff09;的所有真素数。真素数的定义&#xff1a;如果一个正整数 P 为素数&#xff0c;且其反序也为素数&#xff0c;那么 P 就为真素数。 例如&#xff0c;11&#xff0c;13 均为真素数&#xff0c;因为 11 的反序…

Python入门------pycharm加载虚拟环境

pycharm虚拟环境配置&#xff1a; 在按照前面的办法&#xff0c;配置好虚拟环境后,如果我们需要到虚拟环境开发&#xff0c;就需要给编译器配置虚拟环境 1.打开编译器&#xff0c;点击右下角的interpreter选项 2. 点击ADD Interpreter,添加虚拟环境 3. 因为我们使用的是原始…

Hadoop安装报错

报错&#xff1a;ERROR 2023-03-09 21:33:00,178 NetUtil.py:97 - SSLError: Failed to connect. Please check openssl library versions. 解决方案: 在安装失败得客户端执行 编辑 /etc/python/cert-verification.cfg 配置文件&#xff0c;将 [https] 节的 verify 项 设为禁用…

linux上Mysql的安装

1.先检查有没有安装mariadb&#xff0c;有的话将其卸载&#xff0c;不然会和mysql冲突 [rootweb1 ~]# yum list | grep mariadb 2.卸载mariadb,按Y确认 [rootweb1 ~]# yum remove mariadb-libs.x86_64 3.下载mysql [rootweb1 ~]# wget https://downloads.mysql.com/archi…

大模型训练数据白皮书

大模型训练数据白皮书 关键要点一、合成数据解决方案探讨二、ChatGPT的案例分析三、大模型训练所需数据及特点四、多模态、知识性和安全性五、中文大模型发展受限于中式价值观类语料短缺六、高质量数据的重要性及其对模型的影响七、三重不确定性和有效搭配八、从质量、规模、多…

Self-Attention 自注意力机制(二)——实例过程说明

一、自注意力机制核心过程 自注意力机制&#xff08;Self-Attention Mechanism&#xff09;&#xff0c;也称为内部注意力机制&#xff0c;是一种在序列模型中用于捕捉序列内部不同位置之间依赖关系的技术。这种机制允许模型在处理序列时&#xff0c;对序列中的每个元素分配不…

pytorch-pytorch之LSTM

目录 1. nn.LSTM2. nn.LSTMCell 1. nn.LSTM 初始化函数输入参数与RNN相同&#xff0c;分别是input_size&#xff0c;hidden_size和num_layer foward函数也与RNN类似&#xff0c;只不过返回值除了out外&#xff0c;ht变为(ht,ct) 代码见下图&#xff1a; 2. nn.LSTMCell 初…

SAP ABAP性能优化

1.前言 ABAP作为SAP的专用的开发语言&#xff0c;衡量其性能的指标主要有以下两个方面&#xff1a; 响应时间&#xff1a;对于某项特定的业务请求&#xff0c;系统在收到请求后需要多久返回结果 吞吐量&#xff1a;在给定的时间能&#xff0c;系统能够处理的数据量 2. ABAP语…

React工程化笔记

脚手架可以帮助我们快速的搭建一个项目结构&#xff0c;在我们之前学习 webpack 的过程中&#xff0c;每次都需要配置 webpack.config.js 文件&#xff0c;用于配置我们项目的相关 loader 、plugin&#xff0c;这些操作比较复杂&#xff0c;但是它的重复性很高&#xff0c;而且…

SQL注入问题

一、什么是sql注入 public class TestSql {public static void main(String[] args) {Scanner inScanner new Scanner(System.in);System.out.println("请输入用户名");String username inScanner.nextLine();System.out.println("请输入密码");String …

安卓笔记1-Retrofit2请求自定义接口

1、整体功能概述 安卓项目中使用Retrofit2实现和自定义接口的网络交互&#xff0c;通过Postman模拟服务端&#xff0c;创建自定义接口。 作用 前后端开发进度对不齐时&#xff0c;客户端可利用本功能模拟测试数据。备忘。 缺点 retrofit模拟接口需要配置响应数据类&#xff…

2024网络准入控制系统排行|好用的网络准入系统有哪些?

随着数字化转型的深化及网络安全威胁的日益复杂&#xff0c;网络准入控制系统&#xff08;NAC&#xff09;已成为企业安全架构中不可或缺的一部分。NAC系统通过对接入网络的设备进行身份验证、安全检测和策略实施&#xff0c;确保仅允许符合安全标准的设备连接至网络&#xff0…

QT上位机绘制一个表格显示MYSQL数据库(六)

一. QT制作MYSQL表格 database.cpp #include "database.h" #include "ui_database.h"#include <QMessageBox> #include <QDebug> #include <QSqlError>database::database(QWidget *parent) :QWidget(parent),ui(new Ui::database) {u…

【ollama】ollama运行GLM4-9B和CodeGeeX4-ALL-9B

一、下载GGUF模型 glm-4-9b-chat-GGUFcodegeex4-all-9b-GGUF 使用modelscope下载 先安装 pip install modelscope 命令1 modelscope download --modelLLM-Research/glm-4-9b-chat-GGUF --local_dir . glm-4-9b-chat.Q5_K.gguf命令2 modelscope download --modelLLM-Researc…

条件匹配工具之ACL概述

基本概念 ACL&#xff0c;即Access Control List&#xff08;访问控制列表&#xff09;&#xff0c;每个ACL但是是由单条或多条Rule&#xff08;规则&#xff09;组成的一个集合 技术背景&#xff1a; 1.用户需求&#xff1a; 用户对网络服务体验的要求越来越高&#xff0c…

学习测试9-接口测试 3-jmeter

jmeter启动 测试计划 1 创建线程组 2 创建http请求 数据类型 from表单数据可以通过剪切板直接粘贴 JSON数据需要从括号开始复制 3 查看结果树 4 http cookie管理器&#xff0c;可以记住登录状态 内部不用设置 5 断言 系统返回的信息进行判断 系统返回“新增会议信息成功” …

python--实验13 异常处理

目录 知识点 异常概述 异常类 异常处理 捕获简单异常 原理 示例 异常处理except 原理及代码格式 try工作原理 标记程序上下文&#xff0c;异常发生时跳转 代码示例 终止行为finally 抛出异常raise 原理 代码格式 示例 自定义异常 原理 示例 断言assert 判…