当前位置: 首页 > news >正文

1.easypan-登录注册

1.0 遇到的问题

1.0.1 JRebel 导致的 Bug

场景:最开始 yml 中数据库的信息配置错了,修改对后从新构建项目运行(使用了 Jrebel),没有重启,导致一直错误

原因:JRebel 热加载插件缓存了旧的数据库配置…,他不会热加载 yml 配置文件

1.0.2 APIFox 插件导致请求失败

场景:更改了请求配置,原本是@RequestMapping,请求失败,改为争取的@GetMapping,还是请求失败

原因:更改后没有刷新 APIFox 插件,导致还是原本的请求

1.1 图形验证码

1.1.1 当前方案

  1. 自写 创建验证码图像类

  2. 前端 api 增加 time 字段保证每次请求都不同,避免查询缓存,后端不用处理 time 字段

  3. 设置响应头禁止缓存该 HTTP 请求

    • 这三个响应头共同构成了防御性缓存策略,确保:

    • 用户不会看到缓存的旧验证码

    • 代理服务器不会返回历史数据

    • 浏览器每次都必须从服务器获取新验证码

    • Tomcat 默认是 no-cache 的,设置上更保险

  4. 后端将验证码文本存储到 Session 中

    • 根据传入的 type 判断是 0-登录注册,1-邮箱验证码发送
  5. 响应类型设为 image/jpeg(存储在响应头中)

  6. 将验证码存入该 Session 中

    • 通过type参数支持存储到不同 Session 属性(如普通验证码和邮箱验证码分开存储)

    • 这样客户端只能看到图片,无法直接获取或修改验证码内容

    • yml 中设置 session:timeout: PT60M 会话 60 分钟后过期

    • Session ID 通过 Set-Cookie 响应头自动返回

    • 默认 Cookie 名称为 JSESSIONID(Tomcat)或 SESSION(Spring Session)

    • 浏览器后续请求会自动携带该 Cookie

    • Session 由 Tomcat 自行管理,不显示禁用 session 的话 Tomcat 还会创建 Session 到内存中,通过 JESSIONID Cookie 维护会话

  7. 将二进制图形验证码流写入响应体中返回给前端

    • 之前写的 API 都是以 RESTAPI 的格式返回 JSON 数据,这里直接输出响应,Tomcat 将内存中的二进制流(封装后的响应报文)通过 Socket 发送

    验证码为什么采用这种方式?

    • 性能考虑:二进制流直接输出效率更高

    • 资源管理:避免图片数据在内存中多次转换

    • 协议要求:图片响应需要精确控制 Content-Type 等头信息

    • 框架限制:Spring 的消息转换器主要针对结构化数据设计

1.1.2 其他方案

  1. 使用第三方库:Kaptcha 库,简单易用,功能丰富,支持多种干扰效果

  2. 基于 SVG 实现,矢量图形不失真,文件体积小

  3. 行为验证码(如滑动拼图)

  4. Redis 存储方案-支持分布式

1.2 邮箱验证码

1.2.1 当前方案

  1. 前端传入 email 和图形验证码,以及 type:0-注册,1-找回密码

  2. 获取 session 中存储的 code 做比较,没问题之后发送验证码

  3. 先判断是否为注册,校验邮箱是否已经注册

  4. 生成验证码并发送给用户短信,使用 spring 自带的 mail 相关工具包封装邮件

  5. 封装信息:邮箱相关信息,这里短信内容默认配置存入 redis,封装了 RedisUtil 常用方法,Redis 的相关操作放入了 RedisComponent 中

  6. 发送邮件后先将旧的验证么标识为已用,再封装将新验证码信息存入数据库

1.2.2 可优化的点

  1. 增加 IP 限制,防刷

  2. 增加邮箱发送频率限制

  3. 异步发送邮件,避免同步逻辑阻塞

  4. 邮件发送失败重试机制

  5. 数据库存储改为 redis 存储验证码

  6. 分布式锁防止并发(多次重复请求)

  7. 运维方面,日志、限流控制

1.2.3 其他方案

  1. 第三方验证码服务

  2. 自建验证码服务

    • 基于 Spring Cloud 的微服务架构

    • 基于消息队列的异步处理

    • 基于分布式缓存的存储方案

  3. redis+token

1.2.4 MP 查询方案

引入 Mybatis-Plus 后,IService 内部会调用 BaseMapper 类,功能更强大,在服务层获取数据库信息的方案有

  • 查询本表的方案:

    • 继承 BaseMapper 方法

    • Lambda 表达式方式 (推荐),使用 IService 中的 lambda 方法

    • 链式调用方式

  • 查询其他表的方案:

    • 通过注入的 Mapper 查询 (当前代码方式)

    • 自定义 Mapper 方法 (需在 Mapper 中定义)

    • 通过 Service 调用

    • 使用 Db 静态工具类,减少循环依赖注入的风险(推荐)

1.3 AOP 实现参数校验

1.3.1 实现步骤

  1. 引入 AOP 依赖

  2. 定义自定义注解(可选)

  3. 创建切面类并注册为 Bean

    • 使用@Pointcut 定义切点

    • 编写@Before,@After,@Around 等通知方法

    • 获取方法和参数信息

    • 实现业务逻辑(如数据库字段内容添加、参数校验)

    • 统一异常处理与日志记录

  4. 在目标方法上使用注解

1.3.2 对比其他项目

苍穹外卖、黑马点评中是使用 MVC 的 Interceptor 统一拦截请求然后校验的

这里 AOP 自己实现

  • 更细粒度的控制(方法级别)

  • 可以结合自定义注解灵活控制

  • 不局限于 Web 层,可应用于 Service 层

对比建议:

  • 对于纯 Web 请求的登录校验,推荐使用拦截器方案,因为:

    1. 更符合 MVC 架构思想

    2. 性能更好(AOP 会有额外代理开销)

    3. 更易获取 Web 相关对象

  • 考虑 AOP 的场景:

    1. 需要方法级别的细粒度控制

    2. 校验逻辑需要复用至非 Web 组件

    3. 已有基于注解的权限体系

1.4 登录注册&CRUD

1.4.1 登录逻辑

  1. 账号密码登录,先验证图形码

  2. 再验证账号密码,“记住我”1 前端存储的是 md5 加密后的密码

  3. 更新登录时间

  4. 返回给前端基础的用户信息

1.4.2 注册逻辑

  1. 校验图形验证码

  2. 验证邮箱、昵称是否存在

  3. 验证邮箱验证码

  4. 初始化用户云盘空间信息

  5. 保存用户信息到数据库

1.4.3 头像获取

  1. 直接是存储二进制文件到本地

  2. 先根据用户 id 拼接图像名称查找

  3. 没有则使用默认头像

1.4.4 其他

密码更新、重置

退出登录

头像更新 - 直接创建新的头像文件

1.4.5 存在问题

  1. MD5 安全性不足-改用 BCrypt

  2. Session 存储方式存在会话劫持风险

  3. 缺少登录失败次数限制

  4. 缺少密码强度校验

1.4.6 其他方案

  1. JWT + Redis 方案

  2. OAuth2.0 方案:支持第三方登录

  3. Spring Security:安全性高

1.5 登录后默认行为

1.5.1 获取用户默认信息

因为这里采用的是 session 认证,要根据 session 去内存中获取用户信息,所以单独封装了 ABaseController 里面封装了获取用户信息的方法,方便多个接口调用获取。

而苍穹外卖是 JWT+ThreadLocal 方案则是登录后返回给前端 JWT,以后请求先拦截器拦截请求获取 JWT 然后解析出用户信息(包含唯一标识)然后存入 ThreadLocal 中,方便后续直接使用。

而黑马点评是在登录后生产随机 token 返回给前端,并将用户信息作为 value,token 作为小 key 存入 redis 的 hash 中,以后请求携带 token,拦截然后去 redis 中做校验,将用户信息存入 ThreadLocal 中

这里获取用户默认信息以及从 redis 中获取用户的空间使用信息,如果 redis 中没有则先查数据库再缓存并返回

1.5.2 获取文件列表

  1. 先获取具体的文件类型:前端传来的与数据库存储的有个映射

  2. 然后根据 session 分页查询用户文件信息


文章转载自:
http://chayote.riewr.cn
http://cadaverize.riewr.cn
http://burstproof.riewr.cn
http://attributive.riewr.cn
http://biocellate.riewr.cn
http://cameralist.riewr.cn
http://ceder.riewr.cn
http://africanization.riewr.cn
http://adaxial.riewr.cn
http://baseburner.riewr.cn
http://calycular.riewr.cn
http://antiestrogen.riewr.cn
http://bigoted.riewr.cn
http://brandish.riewr.cn
http://authorise.riewr.cn
http://carbamino.riewr.cn
http://bedizen.riewr.cn
http://abbreviator.riewr.cn
http://alec.riewr.cn
http://capitulary.riewr.cn
http://bootery.riewr.cn
http://autocontrol.riewr.cn
http://breastpin.riewr.cn
http://bellwaver.riewr.cn
http://aback.riewr.cn
http://caenogenesis.riewr.cn
http://butyrate.riewr.cn
http://allier.riewr.cn
http://ariose.riewr.cn
http://batteries.riewr.cn
http://www.dtcms.com/a/281271.html

相关文章:

  • AbMole小课堂 | Angiotensin II(血管紧张素Ⅱ)在心血管研究中的多元应用
  • 基于51单片机和16X16点阵屏、矩阵按键的小游戏《俄罗斯方块》
  • 清理C盘--办法
  • python的形成性考核管理系统
  • 学习笔记(37):构建一个房价预测模型,并通过可视化全面评估模型效果
  • Java 异常处理详解:从基础语法到最佳实践,打造健壮的 Java 应用
  • Linux进程信号--0、序章
  • Servlet规范 、Tomcat容器、Springmvc框架
  • Quick API:赋能能源行业,化解数据痛点
  • 构建高性能微服务架构:基于Kubernetes与gRPC的深度实践
  • 缓存穿透的“黑暗森林”假说——当攻击者学会隐藏恶意流量
  • MySQL索引与事务详解:用大白话讲透核心概念
  • sundog公司的SilverLining SDK库实现3d动态云层和下雨、下雨、雨夹雪效果
  • React源码4 三大核心模块之一:Schedule,scheduleUpdateOnFiber函数
  • 美设备垄断破冰:新启航 3D 白光干涉仪的纳米级 “逐鹿” 之路
  • 基于cornerstone3D的dicom影像浏览器 第二章,初始化页面结构
  • 航空发动机气膜冷却孔激光频率梳 3D 轮廓检测方法探究
  • 【Qt】QWidget核心属性
  • 【数据结构】单链表练习(有环)
  • MYSQL练习2
  • Java 集合 示例
  • python学智能算法(二十)|SVM基础概念-感知机算法及代码
  • SAP把运费加入到物料成本估算
  • 使用 Aerich 进行 FastAPI 数据库迁移指南
  • redis红锁
  • GitHub 上 Star 数量前 8 的开源 Web 应用项目
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pandas’问题
  • centos8集群部署etcd
  • 【12】MFC入门到精通——MFC 消息对话框 MessageBox()和AfxMessageBox() 解析 示例 及 应用实例
  • 【目标追踪】MUTR3D: A Multi-camera Tracking Framework via 3D-to-2D Queries