验证码

1. 方法注释

2. 请求映射注解

1
@RequestMapping(value = "/checkCode")
  • 含义:这是 Spring Web 框架中的注解。
  • 作用:它告诉 Spring 框架,当用户访问 URL 地址(比如 http://你的域名/checkCode)时,就执行下面这个 checkCode 方法。

3. 方法定义

4. 生成验证码对象

1
ArithmeticCaptcha captcha = new ArithmeticCaptcha(100, 42); //验证码的长度和宽度
  • 含义:这行代码创建了一个算术验证码对象。
  • ArithmeticCaptcha:这是一个第三方库(通常是 EasyCaptcha)里的类,专门用来生成“加减乘除”类型的验证码(例如:3+5=?)。
  • new ArithmeticCaptcha(100, 42):构造函数,设置生成的验证码图片的宽度为100像素高度为42像素

5. 获取验证码的答案

1
String code = captcha.text();
  • 含义:获取这道算术题的正确答案。
  • captcha.text():如果图片显示的是 2*6=?,那么这个方法就会返回字符串 "12"。我们需要把这个答案存起来,等会儿用户输入后进行比对。

6. 将答案存入 Redis

1
String checkCodeKey = redisComponent.saveCheckCode(code);
  • 含义:将验证码答案存入缓存,并获取一个唯一的 Key。
  • redisComponent:这是一个自定义的工具类,用来操作 Redis 数据库(一种内存缓存数据库,速度很快)。
  • saveCheckCode(code):调用这个方法,把刚才的答案 code(比如 “12”)存进 Redis。
  • checkCodeKey:Redis 为了找到刚才存的数据,返回的一个唯一标识符(类似“取件码”)。一会儿要把这个 Key 发给前端。

7. 生成图片的 Base64 字符串

1
String checkCodeBase64 = captcha.toBase64();
  • 含义:把生成的验证码图片转换成一串字符串。
  • toBase64():直接返回图片文件不太方便,这个方法把图片变成了一长串字符(Base64 编码)。前端浏览器拿到这串字符后,可以直接把它还原成图片显示出来。

8. 组装返回数据

1
CheckCodeVO checkCodeVO = new CheckCodeVO(checkCodeBase64, checkCodeKey);
  • 含义:创建一个“视图对象(VO)”,把要返回给前端的东西打包在一起。
  • CheckCodeVO:这是一个自定义类,通常包含两个属性:
    1. 图片的 Base64 字符串(给用户看的)。
    2. Redis 的 Key(用来验证的)。

9. 返回成功响应

1
2
    return getSuccessResponseVO(checkCodeVO);
}
  • 含义:将打包好的数据放入统一的“成功”格式中并返回。
  • getSuccessResponseVO(...):这通常是父类或工具类里的方法,它把 checkCodeVO 包上一层,告诉前端“这次请求成功了”,然后把数据带回去。

整个流程总结

  1. 用户请求:访问 /checkCode
  2. 生成题目:后台生成一道数学题(如 5+3)。
  3. 存答案:把答案 8 存入 Redis,拿到一个 Key。
  4. 转图片:把题目变成图片,并转成 Base64 字符串。
  5. 返回:把“图片字符串”和“Key”一起发给前端。

前端拿到后,显示图片让用户输入答案,输入完后把“用户输入的答案”和“Key”一起发回后台校验。

登录

1. 接口映射与方法定义

1
2
3
4
5
6
@RequestMapping(value = "/login")
public ResponseVO login(
@NotEmpty String account,
@NotEmpty String password,
@NotEmpty String checkCode,
@NotEmpty String checkCodeKey) {
  • 参数列表
    这里定义了登录需要接收的 4 个参数,都加了 @NotEmpty 注解。
    • @NotEmpty:这是一个校验注解(通常来自 javax.validation),意思是**“这个参数不能为空字符串,也不能为 null”**。如果用户没传,框架会直接报错,不用我们自己写 if (account == null) 了。

2.校验账号密码

1
2
3
if (!account.equals(appConfig.getAdminAccount()) || !password.equals(StringTools.encodeByMD5(appConfig.getAdminPassword()))) {
throw new BusinessException("账号或者密码错误");
}
  • 核心逻辑:比对账号和密码是否与系统配置的一致。

  • 拆解来看

    1. appConfig.getAdminAccount()
      • appConfig 是一个配置类对象。
      • 这里是从配置文件(比如 application.yml)里读取预设好的管理员账号
    2. StringTools.encodeByMD5(...)
      • 这是一个工具类,用来做 MD5 加密
      • 为什么要加密? 因为数据库里(或配置文件里)通常不会存明文密码,存的是加密后的“乱码”。所以要把用户输入的密码也加密,才能比对。

3.无论成败,清理验证码 (finally 块)

1
2
3
} finally {
redisComponent.cleanCheckCode(checkCodeKey);
}
  • finally { ... }
    这是 Java 异常处理的关键字。无论上面的代码是成功执行了,还是中途报错抛出异常了,这里面的代码都一定会执行

  • redisComponent.cleanCheckCode(checkCodeKey)

    • 作用:删除 Redis 中刚才使用的那个验证码。
    • 为什么要删?
      1. 安全性:防止这个验证码被人截获后重复使用。
      2. 不管成功失败都要删
        • 如果登录成功了,验证码当然没用了。
        • 如果登录失败了(比如密码错了),也不能让用户再用刚才的图重试,必须让他刷新一张新图,防止暴力破解。

整个登录流程总结

  1. 接收参数:接收账号、密码、用户输入的验证码、以及验证码的 Key。
  2. 校验验证码:去 Redis 比对,不对就报错。
  3. 校验账号密码:和配置文件比对,不对就报错。
  4. 生成 Token:都对了,生成 Token 存 Redis 并返回给用户。
  5. 清理现场:在 finally 里删掉用过的验证码。

退出

1. 方法定义与获取 Token

1
public ResponseVO logout(@RequestHeader(Constants.TOKEN_ADMIN) String token) {
  • 核心看点:参数是从**请求头(Header)**里获取的,而不是像登录接口那样从 URL 参数或表单里获取。

  • 逐词拆解

    1. @RequestHeader
      这是 Spring 注解,意思是“请从 HTTP 请求的 Header 中提取一个值”。
      • 为什么用 Header?因为 Token(通行证)通常放在 Header 里传输,这是业界标准做法,比放在 URL 里更安全。
    2. Constants.TOKEN_ADMIN
      • Constants 是一个常量类。
      • TOKEN_ADMIN 是里面定义的一个字符串常量(例如可能是 "Admin-Token""Authorization")。
      • 它告诉 Spring 具体去 Header 里找哪个 Key 对应的值。
    3. String token
      把从 Header 里取到的那串 Token 字符串赋值给变量 token

2. 清理 Redis 中的 Token (核心登出逻辑)

1
redisComponent.cleanToken4Admin(token);
  • 含义:这是整个登出功能最核心的一行代码。
  • 逻辑
    • 之前登录成功后,我们把 Token 存在了 Redis 里。
    • 现在调用 cleanToken4Admin 方法,把这个 Token 从 Redis 数据库中删除掉
  • 结果
    • 虽然用户手里可能还存着刚才的 Token 字符串,但服务器端已经不认它了。
    • 下次用户再拿着这个旧 Token 去访问需要登录的接口时,后端去 Redis 一查,发现找不到,就会拒绝访问,从而达到“退出登录”的目的。

整个登出流程总结

  1. 前端请求:在请求头里带上当前的 Token,访问 /logout
  2. 后端删除:后端收到 Token,去 Redis 里把它删掉。
  3. 返回结果:告诉前端删完了。
  4. 后续失效:这个 Token 从此作废,无法再通过它访问系统。