Java實現(xiàn)短信驗證碼服務(wù)的完整代碼示例
首先這里使用的是阿里云的短信服務(wù)。
package com.wzy.util;; import cn.hutool.captcha.generator.RandomGenerator; import com.aliyun.dysmsapi20170525.Client; import com.wzy.entity.Ali; import org.springframework.stereotype.Component; /** * @Author: 顧安 * @Description: * @Date: Create in 17:30 2024/7/23 */ @Component public class SendMsgUtil { /** * 使用AK&SK初始化賬號Client * @return Client * @throws Exception */ private static Ali ali; public SendMsgUtil(Ali ali) { this.ali = ali; } public static Client createClient() throws Exception { com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config() // 必填,請確保代碼運行環(huán)境設(shè)置了環(huán)境變量 ALIBABA_CLOUD_ACCESS_KEY_ID。 .setAccessKeyId(ali.getAccessKeyId()) // 必填,請確保代碼運行環(huán)境設(shè)置了環(huán)境變量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。 .setAccessKeySecret(ali.getAccessKeySecret()); // Endpoint 請參考 https://api.aliyun.com/product/Dysmsapi config.endpoint = "dysmsapi.aliyuncs.com"; return new Client(config); } /* * * API 相關(guān) * @return OpenApi.Params*/ public static com.aliyun.teaopenapi.models.Params createApiInfo() throws Exception { com.aliyun.teaopenapi.models.Params params = new com.aliyun.teaopenapi.models.Params() // 接口名稱 .setAction("SendSms") // 接口版本 .setVersion("2017-05-25") // 接口協(xié)議 .setProtocol("HTTPS") // 接口 HTTP 方法 .setMethod("POST") .setAuthType("AK") .setStyle("RPC") // 接口 PATH .setPathname("/") // 接口請求體內(nèi)容格式 .setReqBodyType("json") // 接口響應(yīng)體內(nèi)容格式 .setBodyType("json"); return params; } public static String sendCode(String phone) throws Exception { com.aliyun.teaopenapi.Client client = createClient(); com.aliyun.teaopenapi.models.Params params = createApiInfo(); String code="123456"; // query params java.util.Map<String, Object> queries = new java.util.HashMap<>(); queries.put("PhoneNumbers", phone); queries.put("SignName", ali.getSignName()); queries.put("TemplateCode", ali.getTemplateCode()); //您正在申請手機注冊,驗證碼為:$[code],5分鐘內(nèi)有效! queries.put("TemplateParam", "{\"code\":\""+codes()+"\"}"); // runtime options com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions(); com.aliyun.teaopenapi.models.OpenApiRequest request = new com.aliyun.teaopenapi.models.OpenApiRequest() .setQuery(com.aliyun.openapiutil.Client.query(queries)); // 復(fù)制代碼運行請自行打印 API 的返回值 // 返回值為 Map 類型,可從 Map 中獲得三類數(shù)據(jù):響應(yīng)體 body、響應(yīng)頭 headers、HTTP 返回的狀態(tài)碼 statusCode。 client.callApi(params, request, runtime); return codes(); } public static String codes(){ // 自定義純數(shù)字的驗證碼(隨機4位數(shù)字,可重復(fù)) RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4); return String.valueOf(randomGenerator); } // public static String code(){ // return String.valueOf(ThreadLocalRandom.current().nextInt(100000,1000000)); // } }
上面的一些屬性沒有直接寫到代碼中,而是模擬真實的開發(fā)場景,寫入application.yml配置文件中,通過定義一個類,然后指定配置文件,在阿里配置類中注入改實體類對象。如下圖所示
@Data @AllArgsConstructor @NoArgsConstructor @Component @ConfigurationProperties("ali.msg") public class Ali { private String accessKeyId; private String accessKeySecret; private String signName; private String templateCode; }
然后需要隨機生成數(shù)字,我這里也使得是hutool工具,需要加入該工具的jar包
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency>
該工具包含各種場景的工具,滿足開發(fā)需求的很多場景,大家可以學(xué)習(xí)一下,隨機生成的代碼如下:
public static String codes(){ // 自定義純數(shù)字的驗證碼(隨機4位數(shù)字,可重復(fù)) RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4); return String.valueOf(randomGenerator); }
生成一個從0到9隨機組成的4位數(shù)。
然后就可以開始編寫我們的真實開發(fā)環(huán)境的發(fā)送驗證碼
@GetMapping("/send") public R sentMsg(String phone){ //判斷前端傳過來的手機號是否正確 if (phone.equals("166x786xxxxx")){ //判斷驗證碼是否已發(fā)送,防止惡意發(fā)送 if (redisTemplate.hasKey("code::"+phone)){ return new R(200,"請不要頻繁點擊",null); } try { //調(diào)用阿里云的接口并拿到前端傳來的手機號 String code = SendMsgUtil.sendCode(phone); //把驗證碼存入到redis緩存中并設(shè)置過期時間 redisTemplate.opsForValue().set("code::"+phone,code,5, TimeUnit.MINUTES); return new R(200,"發(fā)送成功",null); } catch (Exception e) { throw new RuntimeException(e); } } return new R(200,"發(fā)送失敗",null); }
@PostMapping("/login") public R login(@RequestBody LoginVo loginVo){ //拿到緩存中的驗證碼 String code = redisTemplate.opsForValue().get("code::" + loginVo.getPhone()); //拿到緩存中的手機號 String phone = loginVo.getPhone(); //判斷手機號是否正確 if (phone.equals("16627865460")){ //判斷驗證碼是否為空是否正確 if (StringUtils.hasText(loginVo.getCode())&&loginVo.getCode().equals(code)){ //刪除緩存中的驗證碼,防止惡意登入 redisTemplate.delete("code::" + phone); return new R(200,"登入成功",null); }else { return new R(500,"登入失敗",null); } } return new R(500,"登入失敗",null); }
總結(jié)
到此這篇關(guān)于Java實現(xiàn)短信驗證碼服務(wù)的文章就介紹到這了,更多相關(guān)Java實現(xiàn)短信驗證碼服務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot動態(tài)生成接口實現(xiàn)流程示例講解
最近遇到一個需求,需要在程序運行過程中,可以動態(tài)新增接口,自定義接口參數(shù)名稱,基本類型,以及請求方法,請求頭等等。通過幾天的研究,找到了我需要的解決方案2023-01-01Spring中的FactoryBean與BeanFactory詳細(xì)解析
這篇文章主要介紹了Spring中的FactoryBean與BeanFactory詳細(xì)解析,在Spring框架中,FactoryBean和BeanFactory是兩個關(guān)鍵的接口,用于創(chuàng)建和管理對象實例,它們在Spring的IoC(Inversion of Control,控制反轉(zhuǎn))容器中發(fā)揮著重要的作用,需要的朋友可以參考下2023-11-11SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置問題及解決方法
這篇文章主要介紹了SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置,我們可以通過自定義配置數(shù)據(jù)庫配置類來解決這個問題,方式有很多,不同的業(yè)務(wù)采用的方式也不同,下面我簡單的介紹我們項目的使用的方法2022-06-06