zoukankan      html  css  js  c++  java
  • Kaptcha验证码以及Cors 跨域的问题

    Kaptcha验证码

    搭建步骤

    1. 导入依赖

      <!--验证码-->
      <dependency>
          <groupId>com.github.penggle</groupId>
          <artifactId>kaptcha</artifactId>
          <version>2.3.2</version>
      </dependency>
      
    2. 添加配置

      创建一个配置类,并写如下内容

      @Configuration
      public class KaptchaConfig {
      
          @Bean
          public DefaultKaptcha producer()
          {
              
              Properties properties = new Properties();
              properties.put("kaptcha.border", "no");
              properties.put("kaptcha.textproducer.font.color", "black");
              properties.put("kaptcha.textproducer.char.space", "5");
              Config config = new Config(properties);
              DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
              defaultKaptcha.setConfig(config);
              
             /* Properties properties = new Properties();
              //图片边框,合法值yes,no,默认值yes
              properties.put("kaptcha.border","no");
              //边框颜色,合法值rgb(and optional alpha)或者 white,black,blue,默认值black
              properties.put("kaptcha.border.color","blue");
              //边框厚度,合法值>0,默认值为1
              properties.put("kaptcha.border.thickness",2);
              //图片宽度,默认值200
              properties.put("kaptcha.image.width",120);
              //图片高度,默认值50
              properties.put("kaptcha.image.height",40);
              //图片实现类,默认值priv.kerlomz.kaptcha.impl.DefaultKaptcha
              properties.put("kaptcha.producer.impl","priv.kerlomz.kaptcha.impl.DefaultKaptcha");
              //文本实现类,默认值priv.kerlomz.kaptcha.impl.DefaultTextCreator
              properties.put("kaptcha.textproducer.impl","priv.kerlomz.kaptcha.text.impl.DefaultTextCreator");
              //文本集合,验证码值从此集合中获取,默认值abcde2345678gfynmnpwx
              properties.put("kaptcha.textproducer.char.string","abcde2345678gfynmnpwx");
              //验证码长度,默认值为5
              properties.put("kaptcha.textproducer.char.length","5");
              //字体,默认值Arial, Courier(如果使用中文验证码,则必须使用中文的字体,否则出现乱码)
              properties.put("kaptcha.textproducer.font.names","Arial");
              //字体大小,默认值为40px;
              properties.put("kaptcha.textproducer.font.size","40");
              //字体颜色,合法值: r,g,b 或者 white,black,blue,默认值black
              properties.put("kaptcha.textproducer.font.color","black");
              //文字间隔,默认值为2
              properties.put("kaptcha.textproducer.char.space","2");
              //干扰实现类,默认值priv.kerlomz.kaptcha.impl.DefaultNoise
              properties.put("kaptcha.noise.impl","priv.kerlomz.kaptcha.impl.DefaultNoise");
              //干扰 颜色,合法值: r,g,b 或者 white,black,blue,默认值black
              properties.put("kaptcha.noise.color","black");
              *//**图片样式:
               水纹 priv.kerlomz.kaptcha.impl.WaterRipple
               鱼眼 priv.kerlomz.kaptcha.impl.FishEyeGimpy
               阴影 priv.kerlomz.kaptcha.impl.ShadowGimpy, 默认值水纹
               **//*
              properties.put("kaptcha.obscurificator.impl","priv.kerlomz.kaptcha.impl.WaterRipple");
              //背景实现类,默认值priv.kerlomz.kaptcha.impl.DefaultBackground
              properties.put("kaptcha.background.impl","priv.kerlomz.kaptcha.impl.DefaultBackground");
              //背景颜色渐变,开始颜色,默认值lightGray/192,193,193
              properties.put("kaptcha.background.clear.from","255,255,255");
              //背景颜色渐变, 结束颜色,默认值white
              properties.put("kaptcha.background.clear.to","white");
              //文字渲染器,默认值priv.kerlomz.kaptcha.text.impl.DefaultWordRenderer
              properties.put("kaptcha.word.impl","priv.kerlomz.kaptcha.text.impl.DefaultWordRenderer");
      
              Config config = new Config(properties);
              DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
              defaultKaptcha.setConfig(config);
              return defaultKaptcha;*/
              return defaultKaptcha;
          }
      }
      
      
    3. 编写controller,生成验证码图片

          /**
           * 生成验证码
           * @return
           */
          @GetMapping("/captcha")
          public void captcha(HttpServletResponse response) throws IOException {
              response.setHeader("Cache-Control", "no-store, no-cache");
              response.setContentType("image/jpeg");
      
              String code = producer.createText();
              String key = UUID.randomUUID().toString();
      
              BufferedImage image = producer.createImage(code);
      
              ServletOutputStream outputStream = response.getOutputStream();
              ImageIO.write(image,"jpg",outputStream);
      
          }
      

      访问接口,生成验证码

      image-20210713130507686

    因为我们是前后端分离的项目,通过前端地址:localhost:8080/login,调用后端接口localhost:8081/sys/user/captcha时,会报cors跨域的如下错误

    image-20210713133321844

    Cors跨域问题

    1.什么是Cors跨域

    CORS是一个w3c标准,全称是"跨域资源共享"(Cross-origin resource sharing),但一个请求url的协议,域名,端口三者之间任意与当前页面地址不同即为跨域.它允许阅览器向跨源服务器发送XMLHttpRequest请求,从而客服AJAX只能同源使用的限制.
    参考:https://www.cnblogs.com/lishanlei/p/8823823.html

    2.解决方法

    在后端代码中新添加一个corsConfig的配置类,添加如下代码

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    /**
     * @author : sean
     * @version V1.0
     * @Project: vueadmin
     * @Package com.sean.vueadmin.config
     * @date Date : 2021年07月13日 13:29
     * @Description: Springboot解决cors跨域问题
     */
    @Configuration
    public class CorsConfig {
    
    
        private CorsConfiguration buildConfig() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("*");
            corsConfiguration.addAllowedHeader("*");
            corsConfiguration.addAllowedMethod("*");
            return corsConfiguration;
        }
    
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", buildConfig());
            return new CorsFilter(source);
        }
    
    }
    

    然后重启服务后访问,该问题就解决咯

    image-20210713140844545

    特别还需要注意一个问题:后天返回的验证码图片通过输出流的方式返回,前端如何去接收显示图片?

    方式一

    如果只是返回验证码数据流到前端的话,可以使用如下方式

    后台代码:

    image-20210713141143794

    Vue前端:

    image-20210713141247655

    解决方法

    在页面加载的时候就会去向后端发送请求,需要注意的是在请求中添加 responseType:’blob’

     //获取验证码
    getCaptcha(){
        this.$axios.get('/sys/user/captcha',{ responseType: 'blob'}).then(res =>{
    
            this.captchaImg = window.URL.createObjectURL(res.data);
    
            /* this.captchaImg = res.data.data.captchaImg;
                        this.loginForm.token = res.data.data.token;*/
        })
    }
    

    方式二

    如果除了返回验证码图片外还需要返回其它的数据,就不能直接将图片流返回。比如将生成的验证码code保存到redis中,进行登录的时候需要和前端传过来的验证码做检验,此时首先需要从redis中取出保存的验证码的code,因此我们还需要向前端返回一个redis的key回去才能从redis中取出保存的值.

    后台代码controller:

    @GetMapping("/captcha")
    public ResponseResult captcha(HttpServletResponse response) throws IOException {
        //方法二:返回生成的二维码和保存在redis中的key返回给前端
    
        String code = producer.createText();
        String key = UUID.randomUUID().toString();
    
        //将生成的验证码保存到redis中,并且过期时间为5分钟
        redisUtil.hset(Const.CAPTCHA_KEY,key,code,60*5);
    
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(producer.createImage(code),"jpg",outputStream);
    
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String base64Img = "data:image/jpeg;base64," + base64Encoder.encode(outputStream.toByteArray());
    
        return ResponseResult.createBySuccess(MapUtil.builder().put("captchaImg",base64Img).put("token",key).build());
    }
    

    前端vue代码

     //获取验证码
    getCaptcha(){
        this.$axios.get('/sys/user/captcha').then(res =>{
            /*
                      //方法1:直接生成图片返回
                      this.captchaImg = window.URL.createObjectURL(res.data);*/
    
            //方法2:将生成的图片转换成Base64
            this.captchaImg = res.data.data.captchaImg;
            this.loginForm.token = res.data.data.token;
        })
    }
    
  • 相关阅读:
    c语言变量的交换
    牛客网 多多的电子字典
    算法笔记----背包九讲 ③多重背包问题
    统计学习方法 课后习题第五章
    2020.8.2 19:00-21:00 拼多多算法岗笔试
    python构建模块
    leetcode 剑指 Offer 51. 数组中的逆序对
    pytorch的内部计算
    matplotlib
    矩阵微积分
  • 原文地址:https://www.cnblogs.com/seanRay/p/15006197.html
Copyright © 2011-2022 走看看