使用redis保存验证码,传递给vue前端使用,包括后端登录验证

刚开始使redis,踩了不少坑,redis的key不好确定,前端用于刷新验证码不好找到一个确定的值,后面我是从后端给前端传送一个精确到毫秒的时间,前端在刷新验证码的时候,将这个时间传过来作为key使用,同时在登录的时候也传送这个时间戳过来,作为redis value的验证。

1、刷新验证码的时间

/**
     * 获取系统当前毫秒数
     * @since 2019-12-02
     * @return
     */
    @RequestMapping(value = "/redisVerifyCodeTime", method = RequestMethod.POST)
    @ResponseBody
    public BaseResponse redisVerifyCodeTime(HttpServletRequest request) {
        BaseResponse response = BaseResponse.success();
        try {
            Long oldtimestamp=System.currentTimeMillis();
            response.setExtData(ImmutableMap.builder().put("oldtimestamp", oldtimestamp).build());

        }catch (Exception e) {
            logger.error("redisVerifyCodeTime error", e);
            return BaseResponse.fail();
        }
        return response;

    }

 

2、生成验证码并保存到redis中,给前端传递的是一个图片

@RequestMapping("/redisVerifyCode")
public void verifyCode (HttpServletRequest request, HttpServletResponse response) {
    String oldtimestamp = request.getParameter("oldtimestamp");
    BufferedImage image = new BufferedImage(WIDTH, HIGHT,
            BufferedImage.TYPE_INT_RGB);
    // step2,获得画笔
    Graphics2D g = image.createGraphics();
    // step3,¸给画布填充一个随机的颜色
    SecureRandom r = new SecureRandom();
    try{
        r = SecureRandom.getInstance("SHA1PRNG");
    }catch(NoSuchAlgorithmException e){
        e.printStackTrace();
    }
    g.fillRect(0, 0, WIDTH, HIGHT);
    // step4, 在画布上绘画
    g.setColor(new Color(0, 0, 0));
    String str = "0123456789abcdefhijkmnpqrstuvwxyz0123456789ABCDEFGHJKLMNPQRSTUVWXYZ0123456789";
    String code = "";
    for (int i = 0; i < 4; i++) {
        g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
        int h = (int) (20 + 10 * r.nextDouble());
        g.setFont(new Font(null, h, h));
        String ch = String.valueOf(str.charAt(r.nextInt(str.length())));

        //增加验证码识别难度
        AffineTransform trans = new AffineTransform();
        double radians = Math.toRadians(Math.random() * 25.0D + 10.0D);
        int anchorx = 17 * i + 8;
        trans.rotate(radians, anchorx, 20.0D);

        float scaleSize = r.nextFloat() + 0.8F;
        if (scaleSize > 1.0F) {
            scaleSize = 1.0F;
        }
        trans.scale(scaleSize, scaleSize);
        g.setTransform(trans);

        g.drawString(ch, i * WIDTH / 5, h);

        code = code + ch;

    }
    //将验证码保存到redis中
    redisManager.put(VERIFYCODE_PREX + oldtimestamp, code, 10, TimeUnit.MINUTES);
    // 禁止图像缓存。
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Cache-Control", "no-cache");
    response.setDateHeader("Expires", 0);
    response.setContentType("image/jpeg");
    try {
        OutputStream ops = response.getOutputStream();

        javax.imageio.ImageIO.write(image, "jpeg", ops);
    }catch (Exception e){
        e.printStackTrace();
    }

}

3、前端获取验证码

changeVerifyImg(){
      apiVerifyCodeTime({}).then(res => {
        if (res.resultCode == 1000) {//
          this.oldtimestamp = res.extData.oldtimestamp;
        } else {
          this.oldtimestamp = new Date().getTime();
        }
        this.verifyUrl = this.baseURL+'/globalmall/approvalForApp/redisVerifyCode?'+this.timeSign();
      }, err => {

      });
    },
    timeSign(){
      let obj = {oldtimestamp:this.oldtimestamp};
      obj = encryption(obj);
      return obj;
    }

4、前端登录实现

onSubmit() {
      // Disabled submit button
      this.beforeSubmit();

      console.log(sm4.encode({input:this.password,key:this.publicKey}));
      // Login...
      this.$store.dispatch('login',{
        userName: sm4.encode({input:this.userName,key:this.publicKey}),
        password: sm4.encode({input:this.password,key:this.publicKey}),
        verifyCode: sm4.encode({input:this.verifyCode,key:this.publicKey}),
        oldtimestamp: this.oldtimestamp
      }).then(res => {
        // Success handle
        if (res.resultCode == 1000) this.onSuccess(res);//登陆成功
        else {//提示框
          this.showConfirm = true;
          this.message = res.showMsg;
          this.changeVerifyImg();
        }
      }, err => {
        // Error handle
        this.onError(err);
        this.changeVerifyImg();
      })
    },

5、后端登录验证

 String oldtimestamp = request.getParameter("oldtimestamp");
           
            String userName = new SM4Utils().decode(request.getParameter("userName"), SM4_KEY);
            String password = new SM4Utils().decode(request.getParameter("password"), SM4_KEY);
            String verifyCode = new SM4Utils().decode(request.getParameter("verifyCode"), SM4_KEY);

            if(null == verifyCode || "".equals(verifyCode)){
                return BaseResponse.fail("验证码为空,请重新输入");
            }else if(!redisManager.exists(VERIFYCODE_PREX + oldtimestamp)){
                return BaseResponse.fail("验证码过期");
            }else if(!verifyCode.equalsIgnoreCase(redisManager.get(VERIFYCODE_PREX + oldtimestamp))){
                return BaseResponse.fail("验证码错误");
            }

 


版权声明:本文为lijinqing39原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。