Springboot+redis实现用户验证码验证

思路:key为用户邮箱,value为时间戳,当发送验证码的请求进来先检查是否存在这个key然后将时间戳与当前时间戳比较如果小于验证码发送的时间(比如设置了30s内只能发送一次)则返回"您的操作过于频繁"的提示,否则将key-value设置一定的过期时间存到Redis当中,返回验证码
代码:

    @OpLog(title = "邮箱验证码", businessType = "发送")
    @GetMapping(value = "/send-security-code", produces = "application/json;charset=UTF-8")
    public Result<String> sendSecurityCode(@NotBlank(message = "邮箱不能为空")
                                           @Size(min = 1, max = 50, message = "邮箱长度错误")
                                           @Pattern(regexp = CloudDiskConstantConfiguration.REGULAR_VERIFICATION_EMAIL, message = "邮箱格式错误") String email,
                                           @RequestParam(name = "exist", required = false, defaultValue = "false") Boolean exist,
                                           HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=UTF-8");

        // 如果exist值为true,则需要校验当前邮箱是否存在
        if (exist) {
            Assert.notNull(diskUserService.getDiskUserToModel("userEmail", email), "该账户不存在,请重新输入");
        }

        // 根据邮箱地址尝试获取之前的缓存数据
        String cacheData = redisTemplate.opsForValue().get(email);
        if (StrUtil.isNotBlank(cacheData)) {
            // 缓存的时间戳
            long timestamp = JSONObject.parseObject(cacheData).getLong("timestamp");
            // 时间戳 > 当前的时间戳
            if (timestamp >= System.currentTimeMillis()) {
                return Result.fail("您的操作过于频繁");
            }
        }

        // 生成4位数随机安全码
        String securityCode = RandomUtil.randomStringUpper(4);
        // 邮件发送的标题
        String subject = StrUtil.format("验证码:{}", securityCode);
        // 邮件发送的内容
        String content = String.format(CloudDiskConstantConfiguration.MAIL_TEMPLATE_CONTENT, StrUtil.format("您的验证码为: {}<br/>5 分钟内有效。", securityCode));
        // 配置邮件发送
        MailUtil.send(email, subject, content, true);

        // 将结果存入缓存 构建缓存数据
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("securityCode", securityCode);
        // 获取当前时间偏移1分钟后的时间戳
        jsonObject.put("timestamp", DateUtil.offset(new Date(), DateField.MINUTE, 1).getTime());
        //这个api设置了过期时间,最后一个参数是时间单位
        redisTemplate.opsForValue().set(email, jsonObject.toJSONString(), CACHE_TIME, TimeUnit.MILLISECONDS);
        return Result.ok("验证码已发送");
    }
//校验验证码:
 @OpLog(title = "邮箱验证码", businessType = "校验")

    @GetMapping(value = "/verify-security-code", produces = "application/json;charset=UTF-8")
    public Result<Boolean> verifySecurityCode(@NotBlank(message = "请输入邮箱")
                                              @Size(min = 1, max = 50, message = "邮箱长度错误")
                                              @Pattern(regexp = CloudDiskConstantConfiguration.REGULAR_VERIFICATION_EMAIL, message = "邮箱格式错误") String email,
                                              @NotBlank(message = "请输入验证码")
                                              @Size(min = 1, max = 50, message = "验证码长度错误") String code,
                                              HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=UTF-8");

        // 获取邮箱验证码校验结果
        String validationResult = securityCodeValidation(email, code);
        return Result.ok(validationResult.equals("ok"));
    }
  /**
     * 用户邮箱验证码校验
     *
     * @param userEmail          用户邮箱
     * @param authenticationCode 用户输入的验证码
     * @return 校验失败时返回对应失败的字符串 ,否则返回 Ok
     */
    public String securityCodeValidation(String userEmail, String authenticationCode) {
        // 获取缓存数据中的邮箱验证码
        String cacheData = redisTemplate.opsForValue().get(userEmail);
        if (StrUtil.isBlank(cacheData)) {
            return "验证码已过期,请重新获取";
        }

        // 缓存数据中的验证码
        String securityCode = JSONObject.parseObject(cacheData).getString("securityCode");
        if (!securityCode.equalsIgnoreCase(authenticationCode)) {
            return "验证码无效";
        }

        return "ok";
    }

大致流程就是这些了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值