验证码响应结果分析

首先从前端开始进行分析,进入到登录页面,打开开发者工具(f12),找到 network,f5 刷新一下页面,然后,筛选一下,筛选内容为 Fetch/XHR

你会发现列表中有两项内容,我们只需要查看 captchaImage 即可,从名字就可以看出是验证码图片的意思,然后我们查看这个响应结果是什么,响应结果内容如下:

{
"msg": "操作成功",
"img": "...",
"code": 200,
"captchaEnabled": true,
"uuid": "f17217c9743a445298ec85e317f29537"
}
  • captchaEnabled: 验证码是否需要开启,true 开启,false 不开启
  • img:Base64 编码的图片(如果返回二进制会乱码不好理解,前端可以将 Base64 渲染成为图片)
  • uuid:整个系统的 securityId(登录后端有个 session,返回给前端存储到 Cookie 当中,每次带着 Cookie 服务端就知道你已经登录过了,这是传统的方式与做法,ruoyi 使用的是 JWT,但是和传统的 Session 与 Cookie 差不多,换汤不换药)

?> Base64 字符串转图片: https://tool.jisuapi.com/base642pic.html

验证码生成接口分析

通过如上的介绍我们其实已经拿到了验证码接口的名称了,复制一下,去后端当中全局搜这个名字(ctrl + shift + f),会出现如下结果:

到这里我其实介绍了一下,遇到了新项目如何去找接口的位置,这是我比较推荐的一种方式,其它方式就是自己去后端工程当中进行搜寻,这种如果项目比较小还好,太大了我还是推荐我第一种推荐的方式也是现在一直在用的方式进行接口定位。

CaptchaController

captchaImage 方法解刨,如下代码首先去确认了一下验证码是否需要开启:

boolean captchaEnabled = configService.selectCaptchaEnabled();

如果为 false 直接返回响应结果,则前端没有验证码需要进行填写。

!> 这个结果是可以去数据库更改,但是数据库更改了不会立马生效因为更改之前的配置结果保存在 Redis 有一份,所以还需要去删除掉 Redis 在重新加载才会生效

如果 captchaEnabled 为 true,继续往下走,生成验证码,验证码类型分为 mathchar,根据不同的类型去生成,captchaTypeRuoYiConfig 中获取,我们来看看 RuoYiConfig 是什么:

可以看到是从我们的外部配置文件动态装配进来的我们去看看这个文件内容的大致结构,其实就是从 application.yml 中获取,我们自定义了一个关键词为 tienchin 在下面配置了一个 captchaType

math

数值计算的验证码也就是需要自己根据生成的验证码自己计算正确的结果,例如,7+7=?, 那么底层是如何解析这个正确的答案的呢,关键代码如下:

8+1=?@9,根据 @ 截取,前面部分的返回给前端,后面的正确答案会放入 Redis 进行存储,然后通过 Base64 转换返回给前端了。

char

char 就是典型的验证码形式,就是将一串字符以一张图片的形式展示给用户进行填写,我们将正确的验证码结果,存储在 Redis,登录的时候拿着用户输入的与我们 Redis 存在的进行对比即可完成校验。

最终 captchaImage 接口各个部分的代码解释如下:

/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public AjaxResult getCode() {
// 创建一个 AjaxResult 这个是用于返回响应结果是实体类对象
AjaxResult ajax = AjaxResult.success(); // 查看验证码的配置是否开启了验证码
boolean captchaEnabled = configService.selectCaptchaEnabled();
// 将标志写入到响应结果中
ajax.put("captchaEnabled", captchaEnabled); // 如果没有开启则直接返回告诉前端
if (!captchaEnabled) {
return ajax;
} // 得到一个UUID
String uuid = IdUtils.simpleUUID(); // 生成验证码的Redis保存Key
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; // 定义变量
String capStr, code = null; // 定义一个缓冲的图片流用于将验证码写给前端使用转换为流的形式
BufferedImage image = null; // 生成验证码
String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType)) {
// 逻辑略过(因为太简单)
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
} else if ("char".equals(captchaType)) {
// 逻辑略过(因为太简单)
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
} // 写入Redis
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出,创建了一个输出流
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try {
// 逻辑略过(因为太简单)
assert image != null;
ImageIO.write(image, "jpg", os);
} catch (IOException e) {
// 逻辑略过(因为太简单)
return AjaxResult.error(e.getMessage());
} // 逻辑略过(因为太简单)
ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(os.toByteArray()));
return ajax;
}

?> 觉得逻辑清晰写的不错,还请麻烦给个关注与点赞支持一下博主,这将成为博主更新的动力。

TienChin 验证码响应结果分析&验证码生成接口分析的更多相关文章

  1. 第二百七十节,Tornado框架-生成验证码图片,以及验证码结合Session验证

    Tornado框架-生成验证码图片,以及验证码结合Session验证 第一.生成验证码图片  生成验证码图片需要两个必须模块 1.python自带的random(随机模块) 2.Pillow()图像处 ...

  2. php CI框架实现验证码功能和增强验证码安全性实战教程

    php CI框架实现验证码功能和增强验证码安全性实战教程 CodeIgniter简称CI是最流行的一个php MVC框架之一,本人讲从实际项目使用中写系列实战经验,有别与其他的理论讲解文章,会附上实战 ...

  3. C#验证码 使用GDI绘制验证码

    首先展示一下效果图如下: C#中的GDI特别方便,很多方法我们只要简单的调用就可以实现很复杂的功能.具体实现过程如下: 首先创建一个windows窗体应用(测试使用,实际开发winform程序时在需要 ...

  4. 转:Java生成图片验证码(有点仿QQ验证码的意思)

    http://blog.csdn.net/ruixue0117/article/details/22829557 java: VerifyCodeUtils.java package com.fro. ...

  5. 伪验证码(含随机验证码方法)js+css

    HTML----------------------------------------------<!DOCTYPE html><html><head><m ...

  6. python爬虫scrapy框架——人工识别登录知乎倒立文字验证码和数字英文验证码(2)

    操作环境:python3 在上一文中python爬虫scrapy框架--人工识别知乎登录知乎倒立文字验证码和数字英文验证码(1)我们已经介绍了用Requests库来登录知乎,本文如果看不懂可以先看之前 ...

  7. android发送短信验证码并自动获取验证码填充文本框

    android注册发送短信验证码并自动获取短信,截取数字验证码填充文本框. 一.接入短信平台 首先需要选择短信平台接入,这里使用的是榛子云短信平台(http://smsow.zhenzikj.com) ...

  8. Flask实战第43天:把图片验证码和短信验证码保存到memcached中

    前面我们已经获取到图片验证码和短信验证码,但是我们还没有把它们保存起来.同样的,我们和之前的邮箱验证码一样,保存到memcached中 编辑commom.vews.py .. from utils i ...

  9. kubernetes/k8s CNI分析-容器网络接口分析

    关联博客:kubernetes/k8s CSI分析-容器存储接口分析 kubernetes/k8s CRI分析-容器运行时接口分析 概述 kubernetes的设计初衷是支持可插拔架构,从而利于扩展k ...

  10. 基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#)

    基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#) 为了完美解析GLSL源码,获取其中的信息(都有哪些in/out/uniform等),我决定做个GLSL编译器的前端(以后简称编译器或 ...

随机推荐

  1. C# 使用SqlDataAdapter和DataSet来访问数据库

    使用SqlDataAdapter和DataSet来访问数据库 报:已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭 解决方法,使用 using 包住 connectio ...

  2. 如何通过命令部署.Net

    如何通过命令部署.net3.5组件服务 问题:系统安装.net一直报错,无法安装该功能. 问题现象: 终极解决方案: 将windows10系统镜像文件拷贝在硬盘或者U盘中,鼠标右击选择"装载 ...

  3. Flink异步IO

    本文讲解 Flink 用于访问外部数据存储的异步 I/O API. 对于不熟悉异步或者事件驱动编程的用户,建议先储备一些关于 Future 和事件驱动编程的知识. 对于异步 I/O 操作的需求 在与外 ...

  4. 【每日一题】23.Removal (计数DP)

    补题链接:Here 计数DP讲解:Here 这是一个计数类的dp dp[i][j]表示前i个数字中,删除j个元素的方案数 很容易得到转移方程:\(f[i][j] = f[i - 1][j - 1] + ...

  5. mybatis-plus数据批量插入

    为了提高数据处理效率,大量数据需要插入数据时可以采用批量数据插入的策略提高数据插入的效率. 如下是实现方法 1.代码结构 2.实体类 package little.tiger.one.applicat ...

  6. Node版本升级和降级

    https://blog.csdn.net/qq_29262849/article/details/52973095

  7. NodeJS开发服务端实现文件上传下载和数据增删改查

    本文主要讲解已NodeJS作为服务器完成文件的上传下载和数据增删改查,前端框架为Vue3,UI框架为element-plus,Node版本为V16.14.2. 项目场景模拟是开发一个项目管理的系统,支 ...

  8. C#设计模式09——组合模式的写法

    1. 什么是C#组合模式? 组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示"整体/部分"层次结构.使用此模式,客户端可以按相同的方式处理单个对象和对象集合,而不必关 ...

  9. navicat 查看,设计并导出数据库 ER图

    转载请注明出处: 1. navicat 查看 ER 图,有两种方式: 第一种:选中数据库,并右键点击选中逆向数据库到模型. 第二种:可以在工具栏点击查看,选中 ER,打开 某数据库,便会展示 该数据库 ...

  10. centos7_Lnmp编译安装

    17年面试运维岗位的时候,面试官要求输出一份lnmp编译的操作文档,于是有了如下安装nginx+php+mysql,进入正题: 准备环境 环境:centos7.3 软件:nginx-1.12.1 + ...