谷粒商城实战笔记-214~219-商城业务-认证服务-验证码防刷校验
文章目录
- 一,验证码防刷校验
- 1,第三方服务提供发送短信的接口
- 2,登录服务提供给前端的接口
- 二,215-商城业务-认证服务-一步一坑的注册页环境
- 三,商城业务-认证服务-异常机制
- 四,217-商城业务-认证服务-MD5&盐值&BCrypt
- 五,218-商城业务-认证服务-注册完成
- 六,219-商城业务-认证服务-账号密码登录完成
- 总结
包含:
- 214-商城业务-认证服务-验证码防刷校验
- 215-商城业务-认证服务-一步一坑的注册页环境
- 216-商城业务-认证服务-异常机制
- 217-商城业务-认证服务-MD5&盐值&BCrypt
- 218-商城业务-认证服务-注册完成
- 219-商城业务-认证服务-账号密码登录完成
一,验证码防刷校验
1,第三方服务提供发送短信的接口
短信服务可以给多方提供服务,所以要提供一个接口,接受电话号码和code,调用接口将code发送给指定的电话号码。
@Controller
@RequestMapping(value = "/sms")
public class SmsSendController {@Resourceprivate SmsComponent smsComponent;/*** 提供给别的服务进行调用* @param phone* @param code* @return*/@GetMapping(value = "/sendCode")public R sendCode(@RequestParam("phone") String phone, @RequestParam("code") String code) {//发送验证码smsComponent.sendCode(phone,code);return R.ok();}}
2,登录服务提供给前端的接口
@Controller
public class LoginController {@Resourceprivate ThirdPartFeignService thirdPartFeignService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@ResponseBody@GetMapping(value = "/sms/sendCode")public R sendCode(@RequestParam("phone") String phone) {//1、接口防刷String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);if (StrUtil.isNotEmpty(redisCode)) {//活动存入redis的时间,用当前时间减去存入redis的时间,判断用户手机号是否在60s内发送验证码long currentTime = Long.parseLong(redisCode.split("_")[1]);if (System.currentTimeMillis() - currentTime < 60000) {//60s内不能再发return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(),BizCodeEnum.SMS_CODE_EXCEPTION.getMessage());}}//2、验证码的再次效验 redis.存key-phone,value-codeint code = (int) ((Math.random() * 9 + 1) * 100000);String codeNum = String.valueOf(code);String redisStorage = codeNum + "_" + System.currentTimeMillis();//存入redis,防止同一个手机号在60秒内再次发送验证码stringRedisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,redisStorage,10, TimeUnit.MINUTES);thirdPartFeignService.sendCode(phone, codeNum);return R.ok();}}
这段代码用于共前端调用,发送短信验证码,其主要作用如下:
-
接口防刷机制:首先检查Redis中是否已经为提供的手机号码
phone
存储了验证码。如果存在,并且当前时间与存储验证码时的时间差小于60秒,则认为请求过于频繁,返回错误信息,阻止用户在短时间内重复发送验证码。 -
生成验证码:如果用户请求发送验证码的频率正常,代码将生成一个六位数的随机验证码。
-
存储验证码到Redis:将生成的验证码和当前时间戳拼接,存储到Redis中,其中键为手机号码,值为验证码和时间戳的组合。这用于验证验证码的有效性,并防止同一个手机号在60秒内再次发送验证码。
-
调用第三方服务发送验证码:通过Feign服务调用第三方服务(例如短信服务提供商)发送验证码到用户的手机上。
-
返回操作结果:如果验证码发送成功,方法返回一个表示操作成功的响应。
关于发送验证的两个要点:
- 1,因为要验证用户输入的验证码是否正确,需要后台将生成的验证码进行保存,因为不需要持久化,所以保存在redis中。
- 2,为了防止恶意调用,所以要在后台进行验证,60秒内只能调用一次,超过一次的返回错误,不允许重发。
二,215-商城业务-认证服务-一步一坑的注册页环境
这一节的主要内容是:
- 校验前端登录参数是否符合标准
- 如果不符合校验规则,将错误信息返回给前端,由前端回显
封装前端参数的VO,VO使用了JSR303校验,简化代码。
@Data
public class UserRegisterVo {@NotEmpty(message = "用户名不能为空")@Length(min = 6, max = 19, message="用户名长度在6-18字符")private String userName;@NotEmpty(message = "密码必须填写")@Length(min = 6,max = 18,message = "密码必须是6—18位字符")private String password;@NotEmpty(message = "手机号不能为空")@Pattern(regexp = "^[1]([3-9])[0-9]{9}$", message = "手机号格式不正确")private String phone;@NotEmpty(message = "验证码不能为空")private String code;}
这里有个小细节,前端登录界面登录请求会携带参数,校验不通过,需要把错误信息返回给前端,因为使用了了模板引擎,课程中采用请求转发的方式,实际上在直接返回错误信息应该也是可以的,只要前端做好适配。
三,商城业务-认证服务-异常机制
登录请求的参数校验通过后,需要验证验证码是否正确,从redis中取出存储的验证码,然后校验即可。
如果验证码校验通过,下一步要调用member会员服务的接口,注册会员。
会员服务提供的这个接口中,需要做一些校验:
- 用户名要唯一
- 手机号要唯一
如果校验不通过,通过抛异常的方式将信息抛给controller层。
四,217-商城业务-认证服务-MD5&盐值&BCrypt
对于用户的密码,不能存储明文,必须对其进行加密。
加密有两种方式:
- 不可逆的加密,不能根据密文推出明文
- 可逆的加密,可以根据密文推出密文
为了防止相同的密码有相同的密文,通常采用加盐的方式,这样即使多个用户的密码相同,存储在数据库的密文也不是一样的
课程中采用不可逆的加密,在实际工作中一般也采用不可逆的加密。
MD5是常用的不可逆加密算法,我们使用Spring提供的工具类BCryptPasswordEncoder
对密码进行md5加密。
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();String encode = bCryptPasswordEncoder.encode(vo.getPassword());memberEntity.setPassword(encode);
MD5(Message Digest Algorithm 5,信息摘要算法5)是一种广泛使用的加密算法,用于生成数据的哈希值。
-
压缩性:无论输入数据的长度如何,MD5算法都会生成一个固定长度(128位,即16字节)的哈希值。
-
易于计算:从原始数据计算出MD5值是一个相对简单和快速的过程。
-
抗修改性:对原始数据进行任何微小的改动,哪怕是修改一个字符,都会导致生成的MD5值发生显著的变化。
-
强抗碰撞性:找到两个不同的数据输入,它们具有相同的MD5值,被认为是非常困难的。但是,这并不意味着MD5没有碰撞,实际上,MD5的抗碰撞性已经被证明是不足够的,尤其是在密码学领域。
-
加盐(Salting):为了增加MD5的安全性,可以通过添加一个随机生成的盐值(Salt)与原始数据组合,然后进行MD5加密。数据库中存储加密后的MD5值和盐值。在验证数据时,使用相同的盐值对输入数据进行MD5加密,然后与存储的MD5值进行比较以验证正确性。
五,218-商城业务-认证服务-注册完成
这一节主要调试注册服务的完成。
六,219-商城业务-认证服务-账号密码登录完成
这一节生完成登录的后台接口,主要的逻辑:
- 权限认知服务接收前端页面的参数
- 校验通过后调用会员服务的接口,接口根据参数查询数据库,判断用户名和密码是否正确
总结
-
错误处理:首先检查表单验证结果
result
是否有错误。如果有错误,将错误信息收集并存储到errors
映射中,然后重定向回注册页面。 -
验证码验证:从前端获取用户输入的验证码
code
,然后从Redis中获取存储的验证码redisCode
。如果Redis中有对应的验证码,并且用户输入的验证码与Redis中的验证码匹配,则进行下一步。 -
删除验证码:如果验证码匹配,从Redis中删除该验证码,防止重复使用。
-
远程服务注册:调用远程服务
memberFeignService.register(vos)
进行用户注册。 -
注册结果处理:
- 如果注册成功(
register.getCode() == 0
),重定向到登录页面。 - 如果注册失败,收集错误信息,存储到
errors
映射中,然后重定向回注册页面。
- 如果注册成功(
-
验证码不匹配或不存在处理:如果用户输入的验证码与Redis中的不匹配,或者Redis中没有对应的验证码,收集错误信息,存储到
errors
映射中,然后重定向回注册页面。
整体上,这段代码实现了用户注册时的验证码验证、错误处理和注册结果反馈,确保了注册流程的安全性和用户体验。
相关文章:
谷粒商城实战笔记-214~219-商城业务-认证服务-验证码防刷校验
文章目录 一,验证码防刷校验1,第三方服务提供发送短信的接口2,登录服务提供给前端的接口 二,215-商城业务-认证服务-一步一坑的注册页环境三,商城业务-认证服务-异常机制四,217-商城业务-认证服务-MD5&…...
在华为服务器的openEuler系统中适配Pytorch调用NPU
服务器架构:aarch64 yolov7 和 mindyolo 二选一即可,yolov7是基于pytorch,mindyolo是基于mindspore 本文档基于CANN8.0RC3 , 刚发布比较新,如果有问题,可将CANN版本降低 导读 资料首页:https://www.hiasce…...

MVCC工作原理深入解析
一、事务概述 mysql事务是指一组命令操作,在执行过程中用来保证要么全部成功,要么全部失败。事务是由引擎层面来支持的,MyISM引擎不支持事务,InnoDB引擎支持事务。 事务具有ACID四大特性 原子性(Atomicity࿰…...

使用html+css+js实现完整的登录注册页面
在这篇博客中,我们将讨论如何使用简单的 HTML 和 CSS 构建一个登录与注册页面。这个页面包含两个主要部分:登录界面和注册界面。我们还会展示如何通过 JavaScript 切换这两个部分的显示状态。 页面结构 我们将创建一个页面,其中包含两个主要…...

2024年8月16日(运维自动化 ansible)
一、回顾 1、mysql和python (1)mysql5.7 1.1不需要执行mysql_ssl_rsa_setup 1.2change_master_to 不需要get public key (2)可以使用pymysql非交互的管理mysql 2.1pymysql.connect(host,user,password,database,port) 2.2 cursorconn.cursor() 2.3 cursor.execute("creat…...

荣耀Magicbook x14 扩容1TB固态
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 固态硬盘规格 在官网查看加装固态硬盘的接口规格 https://www.honor.com/cn/laptops/honor-magicbook-x14-2023/ https://club.honor.com/cn/thread-2847379…...
Springboot整合全文检索引擎Lucene
文章目录 前言Lucene的介绍springboot项目中如何整合Lucene简单用法1. 引入依赖2. 其它用到的类2. 创建索引3. 简单搜索4. 更新索引5. 删除索引6. 删除全部索引 Springboot整合Lucene复杂搜索1. 同时标题和内容中查找关键词2. 搜索结果高亮显示关键词3. 分页搜索4. 多关键词联合…...
【深度学习】【语音】TTS, 如何使用Python分析WAV的采样率、比特深度、通道数
文章目录 使用Python分析WAV文件的属性与可视化简介所需环境代码解析可视化音频数据结论使用Python分析WAV文件的属性与可视化 WAV文件录音要求 为了确保录制的音频文件符合TTS模型训练的质量标准,请遵循以下录音要求: 采样率要求:44.1 kHz说明:采样率44.1 kHz(即每秒采样…...

Linux的安装和使用
Linux 第一节 Linux 优势 1. 开源 为什么这么多的的设备都选择使用 Linux?因为它是开源软件(open source software),具有不同的含义。使用一个安全的操作系统工作变得必不可少的事,而 Linux 恰好满足了这个需求。因…...

查看一个exe\dll文件的依赖项
方法 使用一个Dependencies工具,检测exe文件的所有依赖项 工具使用 下载压缩包之后解压,解压后如下图所示 在命令行中运行Dependencies.exe程序会得到帮助菜单 查询某exe的所有依赖项,使用命令 Dependencies.exe -chain <查询文件> …...

高校科研信息管理系统pf
TOC springboot364高校科研信息管理系统pf 第1章 绪论 1.1 研究背景 互联网概念的产生到如今的蓬勃发展,用了短短的几十年时间就风靡全球,使得全球各个行业都进行了互联网的改造升级,标志着互联网浪潮的来临。在这个新的时代,…...

Linux 开机自动挂载共享文件设置
选择一个要共享的文件 点击确定 -> 确定 启动虚拟机 执行下面的命令 /YumSource 是我选择的共享文件夹,自行替换自已选择的文件夹 mkdir -p /mnt/hgfs cat >> /etc/fstab << EOF .host:/YumSource /mnt/hgfs fuse.vmhgfs-fuse allow_other defaul…...
c_cpp_properties.json、launch.json、 tasks.json
在 Visual Studio Code 中,c_cpp_properties.json、launch.json 和 tasks.json 是三个重要的配置文件,它们的作用如下: c_cpp_properties.json: 这个文件用于配置 C/C 扩展的 IntelliSense、编译器路径和包括路径等。它帮助 VS Co…...

mysql 一些知识点 面试用
mysql 1、4个隔离级别与3个现象2、快照读与当前读2.1 可重复读的情况下出现幻读问题的两种情况 3 数据库 常用引擎4、InnoDB存储引擎对MVCC的实现5、索引(重点)5.1 什么是索引5.2 索引的创建与删除5.2.1 查看表中有哪些索引5.2.2 添加索引5.2.3 删除索引 5.3 索引的分类5.4 树数…...

STM32之点亮LED灯
使用固件库实现LED点灯 LED灯: LED灯,是一种能够将电能转化为可见光的半导体器件 控制LED灯: LED灯的正极接到了3.3V,LED灯的负极接到了PA1,也就是GPIOA1引脚 只需要控制PA1为相对应的低电平,即可点亮对…...
Java 多线程练习2 (抽奖比较Runnable写法)
MultiProcessingExercise2 package MultiProcessingExercise120240814;import java.util.ArrayList; import java.util.Collections;public class MultiProcessingExercise1 {public static void main(String[] args) {// 需求:// 在此次抽奖过程中,抽奖…...

使用fastboot更新部分系统
使用fastboot更新部分系统 获取分区信息 > part list sunxi_flash 0Partition Map for UNKNOWN device 0 -- Partition Type: EFIPart Start LBA End LBA NameAttributesType GUIDPartition GUID1 0x00008000 0x000097c5 "boot-r…...
windows 加载portch遇到的错误
import torch 遇到如下错误 File "<stdin>", line 1, in <module> File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\torch\__init__.py", line 148, in <module> raise err OSError: [W…...

如何将 CICD 模版重构为 CICD component?
极狐GitLab 是 GitLab 在中国的发行版,专门面向中国程序员和企业提供企业级一体化 DevOps 平台,用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规,而且所有的操作都是在一个平台上进行,省事省心省钱。可以一键安装极狐GitL…...

数学建模——评价决策类算法(层次分析法、Topsis)
一、层次分析法 概念原理 通过相互比较确定各准则对于目标的权重, 及各方案对于每一准则的权重,这些权重在人的思维过程中通常是定性的, 而在层次分析法中则要给出得到权重的定量方法. 将方案层对准则层的权重及准则层对目标层的权重进行综合, 最终确定方案层对目标…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...