美文网首页
vue3-elementplus-springboot验证码

vue3-elementplus-springboot验证码

作者: 晓晓_1931 | 来源:发表于2023-01-05 01:16 被阅读0次
    image.png
    前端
    <template>
      <el-form 
        :inline="true" 
        ref="ruleFormRef" 
        :model="ruleForm" 
        status-icon 
        :rules="rules" 
        label-width="120px"
        class="demo-ruleForm">
        <!-- 验证码输入框 -->
        <el-form-item label="验证码" prop="verifiCode">
          <el-input v-model="ruleForm.verifiCode" type="text" autocomplete="off" />
        </el-form-item>
        <!-- 验证码图片 -->
        <el-form-item>
          <el-image style="width: 130px; height: 33px" @click="getVerifiCode" :src="url" />
        </el-form-item>
        <!-- 按钮 -->
        <el-form-item>
          <el-button type="primary" @click="submitForm(ruleFormRef)">提交</el-button>
          <el-button @click="resetForm(ruleFormRef)">重置</el-button>
        </el-form-item>
      </el-form>
    </template>
    
    <script setup>
        import { reactive, ref } from 'vue'
        import { FormInstance } from 'element-plus'
        import axios from 'axios'
        //前端必须设置此项,后台session才能获取到值
        axios.defaults.withCredentials = true;
    
        const ruleFormRef = ref(FormInstance)
    
        //记录前端输入的验证码变量
        const ruleForm = reactive({
          verifiCode: '',
        })
    
        //页面加载时获取图片
        const url = ref('http://localhost:8089/getVerifiCode')
    
        //点击图片时获取新验证码
        const getVerifiCode = () => {
          //让参数随机可切换验证码(重新生成,避免浏览器缓存)
          url.value = 'http://localhost:8089/getVerifiCode?' + new Date().getTime();
        }
    
    
        const checkVerifiCode = (rule, value, callback) => {
          if (!value) {
            return callback(new Error('请输入验证码'))
          } else {
            //验证码不为空时去后台验证
            axios.post('http://localhost:8089/checkVerifiCode?verifiCode=' + ruleForm.verifiCode).then((res) => {
              if (res.data == "error") {
                return callback(new Error('验证码错误'))
              }else{
                callback()
              }
            })
          } 
        }
    
        
        //校验
        const rules = reactive({
          verifiCode: [{ validator: checkVerifiCode }]
        })
        //提交
        const submitForm = (formEl) => {
          if (!formEl) return
          formEl.validate((valid) => {
            if (valid) {
              alert('提交成功')
            } else {
              alert('提交失败')
              return false
            }
          })
        }
        //重置
        const resetForm = (formEl) => {
          if (!formEl) return
          formEl.resetFields()
        }
    </script>
    
    
    后端依赖pom.xml
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
      </parent>
      <dependencies> 
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
      </dependencies>
    
    后端controller
    package com.xx.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.io.OutputStream;
     @Controller
    public class CodeController {
    
    
    
        @ResponseBody
        @RequestMapping("/checkVerifiCode")
        public String checkVerifiCode(String verifiCode, HttpServletRequest request )  {
            //获取session中的验证码字符串
            String code  = (String) request.getSession().getAttribute("verificode");
            if(code.equals(verifiCode)) {
                return "ok" ;
            }else {
                return "error" ;
            }
        }
    
        //获取验证码
        @ResponseBody
        @RequestMapping("/getVerifiCode")
        public String getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
            final int width = 200;           // 图片宽度
            final int height = 100;          // 图片高度
            final String imgType = "jpeg";   // 指定图片格式 (不是指MIME类型)
            // 获得 当前请求 对应的 会话对象(需要在输出流之前创建)
            HttpSession session = request.getSession();
            // 获得可以向客户端返回图片的输出流
            final OutputStream output = response.getOutputStream();
            // 创建验证码图片并返回图片上的字符串
            String code = GraphicHelper.create(width, height, imgType, output);
    
            // 存储到当前会话对象的属性中
            session.setAttribute("verificode", code);
            //返回验证码(字符串)
            return code;
        }
    }
    
    
    验证码工具类
    public class GraphicHelper { 
        /**
         * 以字符串形式返回生成的验证码,同时输出一个图片
         * 
         * @param width   图片的宽度
         * @param height  图片的高度
         * @param imgType 图片的类型
         * @param output  图片的输出流(图片将输出到这个流中)
         * @return 返回所生成的验证码(字符串)
         */
        public static String create(final int width, final int height, final String imgType, OutputStream output) {
            StringBuffer sb = new StringBuffer();
            Random random = new Random();
    
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics graphic = image.getGraphics();
    
            graphic.setColor(Color.getColor("F8F8F8"));
            graphic.fillRect(0, 0, width, height);
    
            Color[] colors = new Color[] { Color.BLUE, Color.GRAY, Color.GREEN, Color.RED, Color.BLACK, Color.ORANGE,
                    Color.CYAN };
            // 在 "画板"上生成干扰线条 ( 50 是线条个数)
            for (int i = 0; i < 50; i++) {
                graphic.setColor(colors[random.nextInt(colors.length)]);
                final int x = random.nextInt(width);
                final int y = random.nextInt(height);
                final int w = random.nextInt(20);
                final int h = random.nextInt(20);
                final int signA = random.nextBoolean() ? 1 : -1;
                final int signB = random.nextBoolean() ? 1 : -1;
                graphic.drawLine(x, y, x + w * signA, y + h * signB);
            }
    
            // 在 "画板"上绘制字母
            graphic.setFont(new Font("Comic Sans MS", Font.BOLD, 50));
            for (int i = 0; i < 6; i++) {
                final int temp = random.nextInt(26) + 97;
                String s = String.valueOf((char) temp);
                sb.append(s);
                graphic.setColor(colors[random.nextInt(colors.length)]);
                graphic.drawString(s, i * (width / 6), height - (height / 3));
            }
            graphic.dispose();
            try {
                ImageIO.write(image, imgType, output);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    
    }
    

    注意:后端配置类设置:

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) { 
            registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("*")
                .allowedHeaders("*")
                .maxAge(36000);
        }
    }
    
    或者后端滤过器设置
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json; charset=utf-8");
    response.setHeader("Access-Control-Allow-Credentials","true");  //这个很重要
    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));  //这块不能直接写 "*"
    response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH"); 
    

    前端axios应设置:

    axios.defaults.withCredentials=true;
    

    相关文章

      网友评论

          本文标题:vue3-elementplus-springboot验证码

          本文链接:https://www.haomeiwen.com/subject/ddbdcdtx.html