• SpringBoot 前后端分离 实现验证码操作


    1|0SpringBoot 版本

    本文基于的 Spring Boot 的版本是 2.6.7 。

    2|0 引入依赖

    captcha 一款超简单的验证码生成,还挺好玩的。还有中文验证码,动态验证码. 。在项目中 pom.

    1. <!--验证码-->
    2. <dependency>
    3. <groupId>com.github.whvcse</groupId>
    4. <artifactId>easy-captcha</artifactId>
    5. <version>1.6.2</version>
    6. </dependency>
    • 把生成的验证码结果保存到 redis 缓存中,并设置过期时间。
    • 前端通过提交验证码和 key,其中 key 就是保存到 redis 中的键,通过这个键获取到对应的值,再与前端提交的值对比,相同就通过验证。

    3|1 实现过程

    新建验证码枚举类

    由于 captcha 这款验证码提供了好几种验证码方法,有中文验证码,动态验证码,算术验证码等等,新建一个验证码每周类存放这几种验证码类型。代码如下:

    1. // fhadmin.cn
    2. public enum LoginCodeEnum {
    3. /**
    4. * 算数
    5. */
    6. ARITHMETIC,
    7. /**
    8. * 中文
    9. */
    10. CHINESE,
    11. /**
    12. * 中文闪图
    13. */
    14. CHINESE_GIF,
    15. /**
    16. * 闪图
    17. */
    18. GIF,
    19. SPEC
    20. }

    该类是定义验证码的基本信息,例如高度、宽度、字体类型、验证码类型等等、并且我们把它转成通过 SpringBoot 配置文件类型来定义更加方便。

    1. // fhadmin.cn
    2. @Data
    3. public class LoginCode {
    4. /**
    5. * 验证码配置
    6. */
    7. private LoginCodeEnum codeType;
    8. /**
    9. * 验证码有效期 分钟
    10. */
    11. private Long expiration = 2L;
    12. /**
    13. * 验证码内容长度
    14. */
    15. private int length = 2;
    16. /**
    17. * 验证码宽度
    18. */
    19. private int width = 111;
    20. /**
    21. * 验证码高度
    22. */
    23. private int height = 36;
    24. /**
    25. * 验证码字体
    26. */
    27. private String fontName;
    28. /**
    29. * 字体大小
    30. */
    31. private int fontSize = 25;
    32. /**
    33. * 验证码前缀
    34. * @return
    35. */
    36. private String codeKey;
    37. public LoginCodeEnum getCodeType() {
    38. return codeType;
    39. }
    40. }

    把配置文件转换 Pojo 类的统一配置类

    1. // fhadmin.cn
    2. @Configuration
    3. public class ConfigBeanConfiguration {
    4. @Bean
    5. @ConfigurationProperties(prefix = "login")
    6. public LoginProperties loginProperties() {
    7. return new LoginProperties();
    8. }
    9. }

    定义逻辑验证生成类

    1. // fhadmin.cn
    2. @Data
    3. public class LoginProperties {
    4. private LoginCode loginCode;
    5. /**
    6. * 获取验证码生产类
    7. * @return
    8. */
    9. public Captcha getCaptcha(){
    10. if(Objects.isNull(loginCode)){
    11. loginCode = new LoginCode();
    12. if(Objects.isNull(loginCode.getCodeType())){
    13. loginCode.setCodeType(LoginCodeEnum.ARITHMETIC);
    14. }
    15. }
    16. return switchCaptcha(loginCode);
    17. }
    18. /**
    19. * 依据配置信息生产验证码
    20. * @param loginCode
    21. * @return
    22. */
    23. private Captcha switchCaptcha(LoginCode loginCode){
    24. Captcha captcha = null;
    25. synchronized (this){
    26. switch (loginCode.getCodeType()){
    27. case ARITHMETIC:
    28. captcha = new FixedArithmeticCaptcha(loginCode.getWidth(),loginCode.getHeight());
    29. captcha.setLen(loginCode.getLength());
    30. break;
    31. case CHINESE:
    32. captcha = new ChineseCaptcha(loginCode.getWidth(),loginCode.getHeight());
    33. captcha.setLen(loginCode.getLength());
    34. break;
    35. case CHINESE_GIF:
    36. captcha = new ChineseGifCaptcha(loginCode.getWidth(),loginCode.getHeight());
    37. captcha.setLen(loginCode.getLength());
    38. break;
    39. case GIF:
    40. captcha = new GifCaptcha(loginCode.getWidth(),loginCode.getHeight());
    41. captcha.setLen(loginCode.getLength());
    42. break;
    43. case SPEC:
    44. captcha = new SpecCaptcha(loginCode.getWidth(),loginCode.getHeight());
    45. captcha.setLen(loginCode.getLength());
    46. default:
    47. System.out.println("验证码配置信息错误!正确配置查看 LoginCodeEnum ");
    48. }
    49. }
    50. if(StringUtils.isNotBlank(loginCode.getFontName())){
    51. captcha.setFont(new Font(loginCode.getFontName(),Font.PLAIN,loginCode.getFontSize()));
    52. }
    53. return captcha;
    54. }
    55. static class FixedArithmeticCaptcha extends ArithmeticCaptcha{
    56. public FixedArithmeticCaptcha(int width,int height){
    57. super(width,height);
    58. }
    59. @Override
    60. protected char[] alphas() {
    61. // 生成随机数字和运算符
    62. int n1 = num(1, 10), n2 = num(1, 10);
    63. int opt = num(3);
    64. // 计算结果
    65. int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt];
    66. // 转换为字符运算符
    67. char optChar = "+-x".charAt(opt);
    68. this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2));
    69. this.chars = String.valueOf(res);
    70. return chars.toCharArray();
    71. }
    72. }
    73. }

    控制层定义验证生成接口

    1. // fhadmin.cn
    2. @ApiOperation(value = "获取验证码", notes = "获取验证码")
    3. @GetMapping("/code")
    4. public Object getCode(){
    5. Captcha captcha = loginProperties.getCaptcha();
    6. String uuid = "code-key-"+IdUtil.simpleUUID();
    7. //当验证码类型为 arithmetic时且长度 >= 2 时,captcha.text()的结果有几率为浮点型
    8. String captchaValue = captcha.text();
    9. if(captcha.getCharType()-1 == LoginCodeEnum.ARITHMETIC.ordinal() && captchaValue.contains(".")){
    10. captchaValue = captchaValue.split("\\.")[0];
    11. }
    12. // 保存
    13. redisUtils.set(uuid,captchaValue,loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES);
    14. // 验证码信息
    15. Map<String,Object> imgResult = new HashMap<String,Object>(2){{
    16. put("img",captcha.toBase64());
    17. put("uuid",uuid);
    18. }};
    19. return imgResult;
    20. }

    前端调用接口

    1. <template>
    2. <div class="login-code">
    3. <img :src='/images/loading.gif' data-original="codeUrl" @click="getCode">
    4. </div>
    5. </template>
    6. <script>
    7. methods: {
    8. getCode() {
    9. getCodeImg().then(res => {
    10. this.codeUrl = res.data.img
    11. this.loginForm.uuid = res.data.uuid
    12. })
    13. },
    14. }
    15. created() {
    16. // 获取验证码
    17. this.getCode()
    18. },
    19. </script>

     

    小伙伴们有兴趣想了解内容和更多相关学习资料的请点赞收藏+评论转发+关注我,后面会有很多干货。
    我有一些面试题、架构、设计类资料可以说是程序员面试必备!所有资料都整理到网盘了,需要的话欢迎下载!私信我回复【07】即可免费获取

     

    原文出处:www.shaoqun.com/a/1849540.html

  • 相关阅读:
    后端resection部分(后方交会,PnP、P3P、EPnp、Nakano P3P)
    Web_python_template_injection SSTI printer方法
    设置环境变量不用重启的办法
    信必优再次收到泛亚地区Top级独立上市人寿保险集团感谢信
    python使用opencv实现火焰检测
    博客系统(升级(Spring))(一)创建数据库,创建实例化对象,统一数据格式,统一报错信息
    牛视系统源码定制开发come here,抖音矩阵系统。
    IO Watch:用 Arduino UNO 制造的可编程手表
    Hive 视图和索引
    【无标题】
  • 原文地址:https://blog.csdn.net/wadfdhsajd/article/details/125558480