Java開發(fā)完整短信驗(yàn)證碼功能的全過程
前言
現(xiàn)代互聯(lián)網(wǎng)項(xiàng)目中,很多場(chǎng)景下都需要使用一種叫做驗(yàn)證碼的技術(shù),常用的有圖片驗(yàn)證碼,滑塊驗(yàn)證碼,短信驗(yàn)證碼等,本文章描述的就是短信驗(yàn)證碼的一個(gè)使用教程,從0開始完成一個(gè)驗(yàn)證碼功能的開發(fā)。
閑扯
是不是看著導(dǎo)語很高大上?。?!
我才不會(huì)說是因?yàn)樽罱恢缹懮恫潘囊黄恼?/p>
但是嘛,我要爭(zhēng)取做到水文章也水的特別認(rèn)真,讓讀者可以根據(jù)本文的教程實(shí)現(xiàn)驗(yàn)證碼功能
使用技術(shù)
- Java:所使用的后端技術(shù)
- JSP:所使用的前端技術(shù)
- 阿里云短信服務(wù):發(fā)送短信
- Redis:存儲(chǔ)驗(yàn)證碼 實(shí)現(xiàn)超時(shí)過期以及驗(yàn)證功能
所需知識(shí)儲(chǔ)備
- Java基礎(chǔ)知識(shí)
- Ajax基礎(chǔ)
- Redis基礎(chǔ)
實(shí)現(xiàn)步驟
首先我們需要找一個(gè)提供短信服務(wù)的商戶,隨便在哪里找都一樣,為了避免廣告嫌疑我就不在此推薦了,購買商家的短信服務(wù)后會(huì)拿到一些參數(shù),比如說請(qǐng)求地址,請(qǐng)求方式,token等,如下圖所示
然后找到接口的調(diào)用樣例,按照調(diào)用樣例傳相應(yīng)的參數(shù)即可實(shí)現(xiàn)短信發(fā)送
這步?jīng)]什么說的,就是調(diào)用API,完成這步之后,就可以發(fā)送短信了,當(dāng)然這個(gè)是第一步,距離正式完成還差很遠(yuǎn)。
這里有一個(gè)小的細(xì)節(jié),就是我們發(fā)送短信,其中這個(gè)驗(yàn)證碼是我們自己生成的,然后以參數(shù)的形式傳給接口,所以這里的驗(yàn)證碼需要我們自己產(chǎn)生 貼一段產(chǎn)生驗(yàn)證碼的代碼
// 僅供參考 根據(jù)業(yè)務(wù)去生成即可 // 生成驗(yàn)證碼 StringBuilder builder = new StringBuilder(); for (int i = 0; i < 6; i++) { int random = (int) (Math.random() * 10); builder.append(random); } String code = builder.toString();
第二步要做的操作就是要將第一步發(fā)送的驗(yàn)證碼,如果發(fā)送成功了的話,我們要將該驗(yàn)證碼保存起來,方便后續(xù)的驗(yàn)證,本人這里使用了SpringBoot整合Redis,直接使用RedisTemplente實(shí)現(xiàn)的,和原生實(shí)現(xiàn)是類似的,就是將驗(yàn)證碼和手機(jī)號(hào)存入Redis。
// 其中的ResultEntity是我個(gè)人封裝的一個(gè)返回結(jié)果 保存的是發(fā)送短信的結(jié)果 成功則存入Redis // setRedisKeyValueRemoteWithTimeOut 是自己封裝的一個(gè)方法 功能為存入redis并且設(shè)置超時(shí)時(shí)間 // 發(fā)送驗(yàn)證碼到phoneNum 獲取結(jié)果 ResultEntity<String> resultEntity = CrowdUtil.sendCodeShortMessage( messageProperties.getHost(), messageProperties.getPath(), messageProperties.getMethod(), phoneNum, "注冊(cè)", messageProperties.getAppCode(), messageProperties.getSmsSignId(), messageProperties.getTemplateId()); if (ResultEntity.SUCCESS.equals(resultEntity.getResult())) { // 驗(yàn)證碼 String code = resultEntity.getData(); // 設(shè)置key String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum; // 如果成功則將驗(yàn)證碼存入Redis 過期時(shí)間300秒 獲取存入redis的結(jié)果 ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeOut(key, code, 300, TimeUnit.SECONDS); if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) { return ResultEntity.successWithoutData(); } else { return saveCodeResultEntity; }
第三步實(shí)現(xiàn)短信驗(yàn)證碼的驗(yàn)證
這步驟實(shí)現(xiàn)的功能就是驗(yàn)證短信驗(yàn)證碼是否匹配,這步驟核心操作就是將驗(yàn)證碼從Redis中取出來,和前端傳過來的數(shù)據(jù)進(jìn)行比對(duì),貼代碼
// 可以無視其中的一些拼接操作,這些拼接操作就是做一下標(biāo)識(shí),作為key。 // 核心是getRedisStringValueByKeyRemote方法 作用為獲取Redis中的驗(yàn)證碼 // 這里有一個(gè)注意事項(xiàng)就是驗(yàn)證碼使用過一次后需要?jiǎng)h除redis中的數(shù)據(jù),避免二次驗(yàn)證造成的數(shù)據(jù)不安全。 // 獲取手機(jī)號(hào) String phoneNum = memberVO.getCardnum(); // 拼接redis中的key String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum; // 根據(jù)key查詢r(jià)edis 返回resultEntity 將value存入data ResultEntity<String> redisResultEntity = redisRemoteService.getRedisStringValueByKeyRemote(key); // 獲取結(jié)果集 String result = redisResultEntity.getResult(); if (ResultEntity.FAILED.equals(result)) { modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, redisResultEntity.getMessage()); return "member-reg"; } // 獲取redis的驗(yàn)證碼 String redisCode = redisResultEntity.getData(); if (redisCode == null) { modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS); return "member-reg"; } // 獲取輸入的驗(yàn)證碼 String code = memberVO.getCode(); if (!Objects.equals(redisCode, code)) { modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_FAILED); return "member-reg"; } // 刪除redis中數(shù)據(jù) redisRemoteService.removeRedisKeyRemote(key);
到這里我們驗(yàn)證碼幾乎就結(jié)束了,已經(jīng)實(shí)現(xiàn)了流程,由于我的那個(gè)驗(yàn)證碼套餐過期了,本人又十分貧窮,就沒有測(cè)試樣例啦,但是保證是可用的,前端調(diào)用方式直接一個(gè)Ajax請(qǐng)求調(diào)用發(fā)送驗(yàn)證碼存儲(chǔ)redis,然后在例如測(cè)試或登錄的業(yè)務(wù)中,去匹配驗(yàn)證碼即可。接下來給幾點(diǎn)拓展,各位可以自己實(shí)現(xiàn)
- 實(shí)現(xiàn)控制單手機(jī)號(hào)一天只能發(fā)送三條消息。
- 實(shí)現(xiàn)控制單ip一天只能發(fā)送是三條消息
- 實(shí)現(xiàn)消息60秒不能重復(fù)發(fā)送
總結(jié)
到此這篇關(guān)于Java開發(fā)完整短信驗(yàn)證碼功能的文章就介紹到這了,更多相關(guān)Java短信驗(yàn)證碼功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JAVA實(shí)現(xiàn)利用第三方平臺(tái)發(fā)送短信驗(yàn)證碼
- Java實(shí)現(xiàn)短信驗(yàn)證碼和國際短信群發(fā)功能的示例
- Java實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼功能
- java短信驗(yàn)證碼獲取次數(shù)限制實(shí)例
- Java實(shí)現(xiàn)短信發(fā)送驗(yàn)證碼功能
- java實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼
- java短信驗(yàn)證碼登錄功能設(shè)計(jì)與實(shí)現(xiàn)
- Java實(shí)現(xiàn)短信驗(yàn)證碼服務(wù)的完整代碼示例
相關(guān)文章
Java線上問題排查神器Arthas實(shí)戰(zhàn)原理解析
原先我們Java中我們常用分析問題一般是使用JDK自帶或第三方的分析工具如jstat、jmap、jstack、?jconsole、visualvm、Java?Mission?Control、MAT等,還有一款神器Arthas工具,可幫助程序員解決很多繁瑣的問題,感興趣的朋友一起看看吧2022-01-01解決springboot?druid數(shù)據(jù)庫連接池連接失敗后一直重連問題
這篇文章主要介紹了解決springboot?druid數(shù)據(jù)庫連接池連接失敗后一直重連問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例
本文主要介紹了SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Java 實(shí)戰(zhàn)項(xiàng)目錘煉之小區(qū)物業(yè)管理系統(tǒng)的實(shí)現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)小區(qū)物業(yè)管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11