首頁 > 軟體

Redis實現驗證碼傳送並限制每日傳送次數的範例程式碼

2022-04-18 16:00:16

1、功能

  • 輸入手機號,點選傳送後隨機生成六位數位碼,2分鐘有效
  • 輸入驗證碼,點選驗證,返回成功或失敗
  • 每個手機號每天只能輸3次

2、分析

  • 每個手機每天只能輸3次:incr每次傳送之後+1,當值為3時提示不能傳送,過期時間為當天結束
  • 隨機生成6位數位驗證碼:RandomUtil(hutool)
  • 驗證碼2分鐘有效:放入redis裡並設定過期時間2分鐘
  • 判斷驗證碼是否一致:從redis裡獲取驗證碼和輸入的驗證碼進行比對

3、實現

package cn.ken.blog.controller.common;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.ken.blog.common.constant.Constants;
import cn.ken.blog.common.domain.Result;
import cn.ken.blog.common.enums.ErrorCodeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 驗證碼控制器
 * @author Ken-Chy129
 * @date 2022/4/17 20:28
 */
@RestController
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public class CaptureController {
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    // 生成驗證碼
    @GetMapping("getNumCode")
    public Result<String> getNumCode(String phone) {
        String captureLimitKey = Constants.CAPTCHA_LIMIT_KEY + phone;
        Integer counts = (Integer) redisTemplate.opsForValue().get(captureLimitKey);
        if (ObjectUtils.isEmpty(counts)) {
            // 今天第一次驗證,故之前快取中無該鍵
            // 距離今天結束剩下多少毫秒
            long expire = DateUtil.endOfDay(new Date()).between(new Date(), DateUnit.MS);
            redisTemplate.opsForValue().set(captureLimitKey, 1, expire, TimeUnit.MILLISECONDS);
        } else if (counts < 3) {
            // 沒有超過限制次數
            redisTemplate.opsForValue().increment(captureLimitKey);
        } else {
            // 超過限制次數,不生成驗證碼,直接返回
            return new Result<String>().error(ErrorCodeEnum.OVER_LIMITS);
        }
        // 生成驗證碼
        String code = RandomUtil.randomNumbers(6); // 隨機生成六位數
        String captureCodeKey = Constants.CAPTCHA_CODE_KEY + phone;
        redisTemplate.opsForValue().set(captureCodeKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        return new Result<String>().success(captureCodeKey + ":" + code);
    }
    
    // 驗證驗證碼
    @GetMapping("verify")
    public Result<String> verify(String phone, String code) {
        String captureCodeKey = Constants.CAPTCHA_CODE_KEY + phone;
        String realCode = (String) redisTemplate.opsForValue().get(captureCodeKey);
        if (ObjectUtils.isEmpty(realCode)) {
            // redis中不存在該使用者生成的驗證碼,證明驗證碼以過期銷燬
            return new Result<String>().error(ErrorCodeEnum.OVERDUE_CODE);
        }
        if (realCode.equals(code)) {
            return new Result<String>().success("驗證成功");
        } else {
            return new Result<String>().error(ErrorCodeEnum.ERROR_CODE);
        }
    }
    
//    @Scheduled(cron = "0 0 12 * * ?")
//    private void clear() {
//        redisTemplate.delete()
//    }
}
// Constants類

/**
 * 驗證碼 redis key
 */
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";

/**
 * 每日限制 redis key
 */
public static final String CAPTCHA_LIMIT_KEY = "captcha_limits:";
/**
 * 驗證碼有效期(分鐘)
 */
public static final Integer CAPTCHA_EXPIRATION = 2;

到此這篇關於Redis實現驗證碼傳送並限制每日傳送次數的範例程式碼的文章就介紹到這了,更多相關Redis驗證碼傳送並限制次數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com