前后端分离,登录验证码 实现过程 梳理

写在之前:之前自己写了一个简单的系统,最近几天完善了登录验证码的功能,现在就分享下实现过程 

框架使用了springboot+vue, 

逻辑分析

  1.前端登录页面发起获取验证码图片请求.

  2.服务端收到请求后,生成一个唯一id,对应的验证码图片 以及验证码图片对应的值(这个值使用缓存保存,id-值一一对应,缓存可使用redis或本地缓存,本地缓存适用于单节点服务)、然后把id 和图片返回前端.

  3.前端收到id后保存到登录表单, 收到的图片直接展示到 登录页面

  4.用户输入用户信息和 对应图片的验证码 和之前拿到的id发起登录请求

  5.后端收到请求后,使用id获取缓存中真实的验证码值,然后和用户提交的验证码进行比较,如果相等则认为通过 反之不通过

 

注意点: 在登录成功后需要将对应id中的缓存值remove掉 防止攻击

实现步骤

第一步引入pom:

<dependency>
    <groupId>com.github.whvcse</groupId>
    <artifactId>easy-captcha</artifactId>
    <version>1.6.2</version>
</dependency>

第二步,主要代码

/** 
     * 依据配置信息生产验证码 LoginProperties 可以用配置bean的方式初始化,也可以在调用时自己初始化,里面都是一些验证码的基本参数这里就不展示了
     *  length的长度代表生成验证码内容的个数一般是四个
     * @param properties
     * @return
     */
    private Captcha switchCaptcha(LoginProperties properties)throws Exception {
        Captcha captcha = null;
        synchronized (this) {
            switch (properties.getCodeType()) {
                case ARITHMETIC:
                    //算数类型 
                    captcha = new ArithmeticCaptcha(properties.getWidth(), properties.getHeight(), properties.getLength());
                    break;
                case CHINESE:
                    //中文
                    captcha = new ChineseCaptcha(properties.getWidth(), properties.getHeight(), properties.getLength());
                    break;
                case CHINESE_GIF:
                    //中文闪图
                    captcha = new ChineseGifCaptcha(properties.getWidth(), properties.getHeight(), properties.getLength());
                    break;
                case GIF:
                    //字母数字闪图
                    captcha = new GifCaptcha(properties.getWidth(), properties.getHeight(), properties.getLength());
                    break;
                case SPEC:
                    //字母数字
                    captcha = new SpecCaptcha(properties.getWidth(), properties.getHeight(), properties.getLength());
                    break;
                default:
                    System.out.println("验证码配置信息错误!正确配置查看 LoginCodeEnum ");
            }
        }
       
        //设置默认内置字体
        captcha.setFont(Captcha.FONT_1);
        return captcha;
    }

 返回验证码

//验证码内容
String captchaValue = captcha.text();
//验证码图片base64url  可直接放在前端<img>标签的 :src中展示
string img = captcha.toBase64()

前端代码:

<el-row :gutter="22">
            <el-col :span="18">
              <el-form-item label="" prop="loginCode">
                <el-input prefix-icon="el-icon-message-solid" type="text" placeholder="验证码" v-model="user.loginCode" @keyup.enter.native="submitForm('userForm')"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <img :src="img" @click="createCode()">
            </el-col>
</el-row>

//调用验证码方法
  methods: {
    createCode() {
      //创建验证码
      this.$axios.get("/**/**").then(res => {
        if (res.data.status === 0) {
          this.user.loginId = res.data.data.id;
          this.img = res.data.data.img;
        }
      });
    }
  }

 

效果展示:

 

posted @ 2023-03-16 15:30  loveCrane  阅读(611)  评论(0编辑  收藏  举报