Redis實(shí)現(xiàn)驗(yàn)證碼發(fā)送并限制每日發(fā)送次數(shù)的示例代碼
1、功能
- 輸入手機(jī)號(hào),點(diǎn)擊發(fā)送后隨機(jī)生成六位數(shù)字碼,2分鐘有效
- 輸入驗(yàn)證碼,點(diǎn)擊驗(yàn)證,返回成功或失敗
- 每個(gè)手機(jī)號(hào)每天只能輸3次
2、分析
- 每個(gè)手機(jī)每天只能輸3次:incr每次發(fā)送之后+1,當(dāng)值為3時(shí)提示不能發(fā)送,過期時(shí)間為當(dāng)天結(jié)束
- 隨機(jī)生成6位數(shù)字驗(yàn)證碼:RandomUtil(hutool)
- 驗(yàn)證碼2分鐘有效:放入redis里并設(shè)置過期時(shí)間2分鐘
- 判斷驗(yàn)證碼是否一致:從redis里獲取驗(yàn)證碼和輸入的驗(yàn)證碼進(jìn)行比對(duì)
3、實(shí)現(xiàn)
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; /** ?* 驗(yàn)證碼控制器 ?* @author Ken-Chy129 ?* @date 2022/4/17 20:28 ?*/ @RestController @SuppressWarnings(value = { "unchecked", "rawtypes" }) public class CaptureController { ? ?? ? ? @Autowired ? ? private RedisTemplate redisTemplate; ? ?? ? ? // 生成驗(yàn)證碼 ? ? @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)) { ? ? ? ? ? ? // 今天第一次驗(yàn)證,故之前緩存中無該鍵 ? ? ? ? ? ? // 距離今天結(jié)束剩下多少毫秒 ? ? ? ? ? ? long expire = DateUtil.endOfDay(new Date()).between(new Date(), DateUnit.MS); ? ? ? ? ? ? redisTemplate.opsForValue().set(captureLimitKey, 1, expire, TimeUnit.MILLISECONDS); ? ? ? ? } else if (counts < 3) { ? ? ? ? ? ? // 沒有超過限制次數(shù) ? ? ? ? ? ? redisTemplate.opsForValue().increment(captureLimitKey); ? ? ? ? } else { ? ? ? ? ? ? // 超過限制次數(shù),不生成驗(yàn)證碼,直接返回 ? ? ? ? ? ? return new Result<String>().error(ErrorCodeEnum.OVER_LIMITS); ? ? ? ? } ? ? ? ? // 生成驗(yàn)證碼 ? ? ? ? String code = RandomUtil.randomNumbers(6); // 隨機(jī)生成六位數(shù) ? ? ? ? String captureCodeKey = Constants.CAPTCHA_CODE_KEY + phone; ? ? ? ? redisTemplate.opsForValue().set(captureCodeKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); ? ? ? ? return new Result<String>().success(captureCodeKey + ":" + code); ? ? } ? ?? ? ? // 驗(yàn)證驗(yàn)證碼 ? ? @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中不存在該用戶生成的驗(yàn)證碼,證明驗(yàn)證碼以過期銷毀 ? ? ? ? ? ? return new Result<String>().error(ErrorCodeEnum.OVERDUE_CODE); ? ? ? ? } ? ? ? ? if (realCode.equals(code)) { ? ? ? ? ? ? return new Result<String>().success("驗(yàn)證成功"); ? ? ? ? } else { ? ? ? ? ? ? return new Result<String>().error(ErrorCodeEnum.ERROR_CODE); ? ? ? ? } ? ? } ? ?? // ? ?@Scheduled(cron = "0 0 12 * * ?") // ? ?private void clear() { // ? ? ? ?redisTemplate.delete() // ? ?} }
// Constants類 /** ?* 驗(yàn)證碼 redis key ?*/ public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; /** ?* 每日限制 redis key ?*/ public static final String CAPTCHA_LIMIT_KEY = "captcha_limits:"; /** ?* 驗(yàn)證碼有效期(分鐘) ?*/ public static final Integer CAPTCHA_EXPIRATION = 2;
到此這篇關(guān)于Redis實(shí)現(xiàn)驗(yàn)證碼發(fā)送并限制每日發(fā)送次數(shù)的示例代碼的文章就介紹到這了,更多相關(guān)Redis驗(yàn)證碼發(fā)送并限制次數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring使用Redis限制用戶登錄失敗的次數(shù)及暫時(shí)鎖定用戶登錄權(quán)限功能
- Redis和Nginx實(shí)現(xiàn)限制接口請(qǐng)求頻率的示例
- 如何利用 Redis 實(shí)現(xiàn)接口頻次限制
- spring boot+ redis 接口訪問頻率限制的實(shí)現(xiàn)
- Redis密碼設(shè)置與訪問限制實(shí)現(xiàn)方法
- 基于Redis實(shí)現(xiàn)每日登錄失敗次數(shù)限制
- Redis實(shí)戰(zhàn)記錄之限制操作頻率
- Python利用redis限制用戶重復(fù)刷新帶來的數(shù)據(jù)問題
相關(guān)文章
詳解Centos7下配置Redis并開機(jī)自啟動(dòng)
本篇文章主要介紹了Centos7下配置Redis并開機(jī)自啟動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-11-11基于redis實(shí)現(xiàn)的點(diǎn)贊功能設(shè)計(jì)思路詳解
點(diǎn)贊是我們現(xiàn)在經(jīng)常見到的一個(gè)效果,如朋友圈、微博都有點(diǎn)贊的效果,下面這篇文章主要跟大家分享了基于redis實(shí)現(xiàn)的點(diǎn)贊功能設(shè)計(jì)思路的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家實(shí)現(xiàn)點(diǎn)贊功能具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-05-05Redis 8種基本數(shù)據(jù)類型及常用命令和數(shù)據(jù)類型的應(yīng)用場(chǎng)景小結(jié)
Redis是一種基于內(nèi)存操作的數(shù)據(jù)庫(kù),其中多虧于高效的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了Redis 8種基本數(shù)據(jù)類型及常用命令和數(shù)據(jù)類型的應(yīng)用場(chǎng)景小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Go語言操作RediSearch進(jìn)行搜索方法示例詳解
這篇文章主要為大家介紹了Go語言操作RediSearch進(jìn)行搜索方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12Redis分布式鎖python-redis-lock使用方法
這篇文章主要介紹了Redis分布式鎖python-redis-lock使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Redis?HyperLogLog數(shù)據(jù)統(tǒng)計(jì)輕量級(jí)解決方案詳解
這篇文章主要為大家介紹了Redis?HyperLogLog數(shù)據(jù)統(tǒng)計(jì)輕量級(jí)解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12高并發(fā)場(chǎng)景分析之redis+lua防重校驗(yàn)
這篇文章主要介紹了高并發(fā)場(chǎng)景分析之redis+lua防重校驗(yàn),本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07redis集群實(shí)現(xiàn)清理前綴相同的key
這篇文章主要介紹了redis集群實(shí)現(xiàn)清理前綴相同的key,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10