Java實(shí)現(xiàn)短信驗(yà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()
// 必填,請確保代碼運(yùn)行環(huán)境設(shè)置了環(huán)境變量 ALIBABA_CLOUD_ACCESS_KEY_ID。
.setAccessKeyId(ali.getAccessKeyId())
// 必填,請確保代碼運(yùn)行環(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()); //您正在申請手機(jī)注冊,驗(yàn)證碼為:$[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ù)制代碼運(yùn)行請自行打印 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ù)字的驗(yàn)證碼(隨機(jī)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));
// }
}上面的一些屬性沒有直接寫到代碼中,而是模擬真實(shí)的開發(fā)場景,寫入application.yml配置文件中,通過定義一個(gè)類,然后指定配置文件,在阿里配置類中注入改實(shí)體類對象。如下圖所示
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ConfigurationProperties("ali.msg")
public class Ali {
private String accessKeyId;
private String accessKeySecret;
private String signName;
private String templateCode;
}
然后需要隨機(jī)生成數(shù)字,我這里也使得是hutool工具,需要加入該工具的jar包
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>該工具包含各種場景的工具,滿足開發(fā)需求的很多場景,大家可以學(xué)習(xí)一下,隨機(jī)生成的代碼如下:
public static String codes(){
// 自定義純數(shù)字的驗(yàn)證碼(隨機(jī)4位數(shù)字,可重復(fù))
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
return String.valueOf(randomGenerator);
}
生成一個(gè)從0到9隨機(jī)組成的4位數(shù)。
然后就可以開始編寫我們的真實(shí)開發(fā)環(huán)境的發(fā)送驗(yàn)證碼
@GetMapping("/send")
public R sentMsg(String phone){
//判斷前端傳過來的手機(jī)號是否正確
if (phone.equals("166x786xxxxx")){
//判斷驗(yàn)證碼是否已發(fā)送,防止惡意發(fā)送
if (redisTemplate.hasKey("code::"+phone)){
return new R(200,"請不要頻繁點(diǎn)擊",null);
}
try {
//調(diào)用阿里云的接口并拿到前端傳來的手機(jī)號
String code = SendMsgUtil.sendCode(phone);
//把驗(yàn)證碼存入到redis緩存中并設(shè)置過期時(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){
//拿到緩存中的驗(yàn)證碼
String code = redisTemplate.opsForValue().get("code::" + loginVo.getPhone());
//拿到緩存中的手機(jī)號
String phone = loginVo.getPhone();
//判斷手機(jī)號是否正確
if (phone.equals("16627865460")){
//判斷驗(yàn)證碼是否為空是否正確
if (StringUtils.hasText(loginVo.getCode())&&loginVo.getCode().equals(code)){
//刪除緩存中的驗(yàn)證碼,防止惡意登入
redisTemplate.delete("code::" + phone);
return new R(200,"登入成功",null);
}else {
return new R(500,"登入失敗",null);
}
}
return new R(500,"登入失敗",null);
}總結(jié)
到此這篇關(guān)于Java實(shí)現(xiàn)短信驗(yàn)證碼服務(wù)的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)短信驗(yàn)證碼服務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何自定義Mybatis-Plus分布式ID生成器(解決ID長度超過JavaScript整數(shù)安全范圍問題)
MyBatis-Plus默認(rèn)生成的是 64bit 長整型,而 JS 的 Number 類型精度最高只有 53bit,這篇文章主要介紹了如何自定義Mybatis-Plus分布式ID生成器(解決ID長度超過JavaScript整數(shù)安全范圍問題),需要的朋友可以參考下2024-08-08
Java創(chuàng)建,編輯與刪除Excel迷你圖表的實(shí)現(xiàn)方法
迷你圖是Excel工作表單元格中表示數(shù)據(jù)的微型圖表。本文將通過Java代碼示例介紹如何在Excel中創(chuàng)建迷你圖表,以及編輯和刪除表格中的迷你圖表,需要的可以參考一下2022-05-05
SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解
這篇文章主要介紹了SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
mybatis實(shí)現(xiàn)遍歷Map的key和value
這篇文章主要介紹了mybatis實(shí)現(xiàn)遍歷Map的key和value方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Spring Boot + MyBatisPlus快速實(shí)現(xiàn)單表CRUD的示例
本文主要介紹了Spring Boot + MyBatisPlus快速實(shí)現(xiàn)單表CRUD的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-06-06

