javascript
SpringBoot项目中快速集成腾讯云短信服务SDK实现手机验证码功能
大家春節好!我是程序員阿福,今天過年的日子祝大家在新的一年里健康平安、步步高升、虎年大吉大利、財源滾滾! 今天分享一篇簡短一點的文章,希望在將來工作中需要的時候能夠用得到,如果將來工作中需要實現短信驗證碼功能時可以打開我的公眾號并翻到這篇文章再仔細參考我的實現思路,那么筆者分享這篇文章的用意也就達到了。
前言
幾乎每一個新項目中都會涉及到手機驗證碼的動能,用戶登錄采用手機驗證碼登錄方式、用戶忘記密碼需要密碼修改密碼時以及用戶進行支付確認時也需要用到手機驗證碼。可以說手機驗證碼在各種項目中用的非常多,因此在我們的項目中集成一個短信通知服務是非常有必要的。
筆者為啥選擇了騰訊云短信服務?市面上的短信服務其實是非常多的,包括阿里云短信服務、七牛云短信服務一起其他各大短信服務廠商等等。一是因為筆者平時買的騰訊云產品比較多,包括我的云服務器也是買的騰訊云產品,對騰訊云的產品比較熟悉,用起來也容易上手;二是發現騰訊云的產品相比較阿里的產品要更便宜些,購買金額的門檻也要低一些,50元就可以購買1000條短信服務,而阿里的短信服務購買金額門檻要100元以上。對于個人開發者而言1000條短信服務以及足夠了。最后就是發現騰訊云短信服務的SDK API簡單易用,各個版本客戶端語言的示例都非常詳細,跟著示例一步一步來很容易就能實現自己的需求。下面廢話不多說,直接介紹在我們的項目集成短信通知服務的詳細步驟與演示代碼。
騰訊云短信服務SDK
SDK 3.0是云API 3.0平臺的配套工具,您可以通過SDK使用所有 [短信 API](https://cloud.tencent.com/document/product/382/52077)。新版SDK實現了統一化,具有各個語言版本的SDK` 使用方法相同,接口調用方式相同,錯誤碼相同以及返回包格式相同等優點。
前提條件
- 已開通短信服務,具體操作請參見 國內短信快速入門。
- 如需發送國內短信,需要先 購買國內短信套餐包。
- 已準備依賴環境:JDK 7 及以上版本。
- 已在訪問管理控制臺 >API密鑰管理頁面獲取 SecretID 和 SecretKey。
- SecretID 用于標識 API 調用者的身份。
- SecretKey 用于加密簽名字符串和服務器端驗證簽名字符串的密鑰,SecretKey 需妥善保管,避免泄露。
- 短信的調用地址為sms.tencentcloudapi.com。
相關資料
- 各個接口及其參數的詳細介紹請參見 API 文檔。
- 下載 SDK 源碼請訪問 [Java SDK 源碼](
安裝 SDK
通過Maven安裝
Maven 是 Java 的依賴管理工具,支持您項目所需的依賴項,并將其安裝到項目中。
1 訪問 Maven 官網 下載對應系統 Maven 安裝包進行安裝
2 添加 Maven 依賴項,只需在 Maven pom.xml添加以下依賴項即可:
<dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>3.1.270</version><!-- 注:這里只是示例版本號(可直接使用),可獲取并替換為 最新的版本號,注意不要使用4.0.x版本(非最新版本) --> </dependency>注意事項:
1 版本號僅為示例,請在 Maven 倉庫 獲取最新的版本號并替換
2 Maven 倉庫中顯示的 4.0.11 是廢棄版本,由于 Maven 索引更新問題尚未完全刪除
通過源碼包安裝
1 下載 源碼壓縮包
2 解壓源碼包到您項目中合適的位置
3 將 vendor 目錄下的 jar 包放在 Java 可找到的路徑中
4 引用方法可參考 示例代碼
示例代碼
說明:所有示例代碼僅作參考,無法直接編譯和運行,需根據實際情況進行修改,您也可以根據實際需求使用 API 3.0 Explorer 自動化生成 Demo 代碼。
每個接口都有一個對應的 Request 結構和一個 Response 結構。本文僅列舉幾個常用功能的示例代碼,如下所示。
這里我們只展示發送短信的示例代碼
import com.tencentcloudapi.common.Credential; import com.tencentcloudapi.common.exception.TencentCloudSDKException;//導入可選配置類 import com.tencentcloudapi.common.profile.ClientProfile; import com.tencentcloudapi.common.profile.HttpProfile;// 導入對應SMS模塊的client import com.tencentcloudapi.sms.v20210111.SmsClient;// 導入要請求接口對應的request response類 import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest; import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;/*** Tencent Cloud Sms Sendsms**/ public class SendSms {public static void main(String[] args){try {/* 必要步驟:* 實例化一個認證對象,入參需要傳入騰訊云賬戶密鑰對secretId,secretKey。* 這里采用的是從環境變量讀取的方式,需要在環境變量中先設置這兩個值。* 你也可以直接在代碼中寫死密鑰對,但是小心不要將代碼復制、上傳或者分享給他人,* 以免泄露密鑰對危及你的財產安全。* CAM密匙查詢: https://console.cloud.tencent.com/cam/capi*/Credential cred = new Credential("secretId", "secretKey");// 實例化一個http選項,可選,沒有特殊需求可以跳過HttpProfile httpProfile = new HttpProfile();// 設置代理// httpProfile.setProxyHost("真實代理ip");// httpProfile.setProxyPort(真實代理端口);/* SDK默認使用POST方法。* 如果你一定要使用GET方法,可以在這里設置。GET方法無法處理一些較大的請求 */httpProfile.setReqMethod("POST");/* SDK有默認的超時時間,非必要請不要進行調整* 如有需要請在代碼中查閱以獲取最新的默認值 */httpProfile.setConnTimeout(60);/* SDK會自動指定域名。通常是不需要特地指定域名的,但是如果你訪問的是金融區的服務* 則必須手動指定域名,例如sms的上海金融區域名: sms.ap-shanghai-fsi.tencentcloudapi.com */httpProfile.setEndpoint("sms.tencentcloudapi.com");/* 非必要步驟:* 實例化一個客戶端配置對象,可以指定超時時間等配置 */ClientProfile clientProfile = new ClientProfile();/* SDK默認用TC3-HMAC-SHA256進行簽名* 非必要請不要修改這個字段 */clientProfile.setSignMethod("HmacSHA256");clientProfile.setHttpProfile(httpProfile);/* 實例化要請求產品(以sms為例)的client對象* 第二個參數是地域信息,可以直接填寫字符串ap-guangzhou,或者引用預設的常量 */SmsClient client = new SmsClient(cred, "ap-guangzhou",clientProfile);/* 實例化一個請求對象,根據調用的接口和實際情況,可以進一步設置請求參數* 你可以直接查詢SDK源碼確定接口有哪些屬性可以設置* 屬性可能是基本類型,也可能引用了另一個數據結構* 推薦使用IDE進行開發,可以方便的跳轉查閱各個接口和數據結構的文檔說明 */SendSmsRequest req = new SendSmsRequest();/* 填充請求參數,這里request對象的成員變量即對應接口的入參* 你可以通過官網接口文檔或跳轉到request對象的定義處查看請求參數的定義* 基本類型的設置:* 幫助鏈接:* 短信控制臺: https://console.cloud.tencent.com/smsv2* sms helper: https://cloud.tencent.com/document/product/382/3773 *//* 短信應用ID: 短信SdkAppId在 [短信控制臺] 添加應用后生成的實際SdkAppId,示例如1400006666 */String sdkAppId = "1400009099";req.setSmsSdkAppId(sdkAppId);/* 短信簽名內容: 使用 UTF-8 編碼,必須填寫已審核通過的簽名,簽名信息可登錄 [短信控制臺] 查看 */String signName = "簽名內容";req.setSignName(signName);/* 國際/港澳臺短信 SenderId: 國內短信填空,默認未開通,如需開通請聯系 [sms helper] */String senderid = "";req.setSenderId(senderid);/* 用戶的 session 內容: 可以攜帶用戶側 ID 等上下文信息,server 會原樣返回 */String sessionContext = "xxx";req.setSessionContext(sessionContext);/* 短信號碼擴展號: 默認未開通,如需開通請聯系 [sms helper] */String extendCode = "";req.setExtendCode(extendCode);/* 模板 ID: 必須填寫已審核通過的模板 ID。模板ID可登錄 [短信控制臺] 查看 */String templateId = "400000";req.setTemplateId(templateId);/* 下發手機號碼,采用 E.164 標準,+[國家或地區碼][手機號]* 示例如:+8613711112222, 其中前面有一個+號 ,86為國家碼,13711112222為手機號,最多不要超過200個手機號 */String[] phoneNumberSet = {"+8621212313123", "+8612345678902", "+8612345678903"};req.setPhoneNumberSet(phoneNumberSet);/* 模板參數: 若無模板參數,則設置為空 */String[] templateParamSet = {"5678"};req.setTemplateParamSet(templateParamSet);/* 通過 client 對象調用 SendSms 方法發起請求。注意請求方法名與請求對象是對應的* 返回的 res 是一個 SendSmsResponse 類的實例,與請求對象對應 */SendSmsResponse res = client.SendSms(req);// 輸出json格式的字符串回包System.out.println(SendSmsResponse.toJsonString(res));// 也可以取出單個值,你可以通過官網接口文檔或跳轉到response對象的定義處查看返回字段的定義System.out.println(res.getRequestId());} catch (TencentCloudSDKException e) {e.printStackTrace();}} }SpringBoot項目中集成短信服務
筆者的spring-boot項目用的是2.2.7.RELEASE版本,是之前作者【江南一點雨】開源的一個spring-boot項目叫blog-server。筆者在這個開源項目的基礎上進行了二次開發。手機驗證碼一般具有一定的時效性,過期后就會失效。我們可以借助redis緩存來存儲短信驗證碼,并設置過期時間。等到服務端需要對用戶請求里帶上的驗證碼進行核對時就直接從redis緩存里面取就行了,redis的客戶端我們用的是jedis。因此我們在集成騰訊云短信服務SDK的同時還要集成redis服務。只需要在項目的pom.xml文件dependencies標簽中加入下面三項依賴項即可:
<dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>3.1.222</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.1.0</version></dependency>創建短信簽名和短信模板
登錄騰訊云控制臺后進入國內短信->短信簽名管理頁面
點擊【創建簽名】按鈕創建短信簽名,進入創建簽名頁面,選擇簽名用途、簽名類型、證明類型、填寫簽名內容和申請說明,并上傳證明。簽名內容有一定的限制:長度為2~12字,由中英文、數字組成,內容不包含【】。
簽名用途有兩種:自用或他用,默認為自用;簽名類型有4種,分別是網站、App、公眾號和小程序,每種簽名類型上傳的證明類型與其簽名類型一一對應。騰訊云控制臺短信簽名管理頁面都有詳細的提示,按照提示上傳對應的證明類型截圖即可;申請說明填寫短信用途即可。填寫好之后點擊【確定】按鈕,等待騰訊云后臺審批通過之后才可使用,審批時間一般需要2個小時。
進入短信->正文模板管理點擊【創建正文模板】按鈕進入創建正文模板界面編輯正文模板
模板名稱:自定義;短信類型:個人選擇普通類型,營銷類型需要企業認證的賬戶才可以啟用;短信內容可以點擊使用標準模板,選好后點擊右邊操作列下的藍色字體【使用】即可;申請說明:根據申請用途自定義
填寫好模板名稱和短信內容及申請說明后點擊確定會生成模板ID,在正文模板管理頁面可以看到,這個模擬ID后面會用到,模板ID為短信模板ID列對應的數字。注意:短信模板需要在狀態為已通過之后才可使用。
下面項目中筆者使用之前審核通過的短信簽名和短信模板ID
application.properties添加騰訊云短信配置信息
blog.sms.secretId=<你的騰訊云secretId> blog.sms.secretKey=<你的騰訊云secretKey> blog.sms.appid=<你的騰訊云appid> blog.sms.signName=<短信簽名內容> blog.sms.endpoint=sms.tencentcloudapi.com blog.sms.region=<服務器所在區域,廣州為:ap-guangzhou>新建配置信息類SmsPropperties
@Configuration @ConfigurationProperties(prefix = "blog.sms") public class SmsProperty {private String secretId;private String secretKey;private String appid;private String signName;private String endpoint;private String region;// 省略setter、getter方法}啟用配置屬性類需要在pom.xml文件中添加spring-boot-configuration-processor的依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>同時在啟動類上加上@EnableConfigurationProperties注解
@SpringBootApplication @EnableScheduling//開啟定時任務支持 @EnableConfigurationProperties @MapperScan(basePackages={"org.sang.mapper"},annotationClass = Repository.class) public class BlogserverApplication {public static void main(String[] args) {SpringApplication.run(BlogserverApplication.class, args);} }配置短信發送SmsClient類bean
新建SmsConfig配置類添加SmsClient類bean, 參照發送短信SDK API完成
@Configuration public class SmsConfig {@Resourceprivate SmsProperty smsProperty;@Beanpublic SmsClient smsClient() {Credential cred = new Credential(smsProperty.getSecretId(), smsProperty.getSecretKey());// 實例化一個 http 選項,可選,無特殊需求時可以跳過HttpProfile httpProfile = new HttpProfile();httpProfile.setReqMethod("POST");httpProfile.setConnTimeout(60);/* SDK 默認使用 POST 方法。* 如需使用 GET 方法,可以在此處設置,但 GET 方法無法處理較大的請求 */httpProfile.setEndpoint(smsProperty.getEndpoint());/* 非必要步驟:* 實例化一個客戶端配置對象,可以指定超時時間等配置 */ClientProfile clientProfile = new ClientProfile();/* SDK 默認用 TC3-HMAC-SHA256 進行簽名* 非必要請不要修改該字段 */clientProfile.setSignMethod("HmacSHA256");clientProfile.setHttpProfile(httpProfile);SmsClient client = new SmsClient(cred, smsProperty.getRegion(),clientProfile);return client;}}新建短信服務類
新建SmsService類,并在該類中完成生成隨機碼、參照SDK發送短信API文檔組裝發送短信請求參數,調用SmsClient類bean完成發送短信和RedisTemplate類bean完成手機驗證碼限時存儲。
@Service public class SmsService {private static final Logger logger = LoggerFactory.getLogger(SmsService.class);@Resourceprivate SmsProperty smsProperty;@Resourceprivate SmsClient smsClient;@Resourceprivate RedisTemplate<String, Object> redisTemplate;public SendSmsResponse sendLoginVeryCodeMessage(String phoneNum) {logger.info("secretId={}, secretKey={}", smsProperty.getSecretId(), smsProperty.getSecretKey());SendSmsRequest req = new SendSmsRequest();req.setSenderId(null);req.setSessionContext(null);// 因從配置屬性中獲取中文內容出現亂碼改為在代碼中把簽名內容寫死req.setSign("阿福談Java技術棧");req.setSmsSdkAppid(smsProperty.getAppid());req.setTemplateID(SmsEnum.PHONE_CODE_LOGIN.getTemplateId());req.setPhoneNumberSet(new String[]{phoneNum});String verifyCode = getCode();String[] params = new String[]{verifyCode, "10"};req.setTemplateParamSet(params);logger.info("req={}", JSON.toJSONString(req));try {SendSmsResponse res = smsClient.SendSms(req);if ("Ok".equals(res.getSendStatusSet()[0].getCode())) {// 發送短信驗證碼成功則將驗證碼保存到redis緩存中redisTemplate.opsForValue().set("loginVerifyCode:"+phoneNum, verifyCode, 10, TimeUnit.MINUTES);}return res;} catch (TencentCloudSDKException e) {logger.error("send message failed", e);throw new RuntimeException("send message failed, caused by " + e.getMessage());}}/*** 生成6位隨機數字驗證碼* @return*/private String getCode() {String numbers = "1234567890";StringBuilder builder = new StringBuilder();Random random = new Random();for(int i=0; i<6; i++) {int index = random.nextInt(10);builder.append(numbers.charAt(index));}return builder.toString();} }完成發送短信驗證碼控制器方法
在UserController類中添加發送短信驗證碼方法
@Resourceprivate SmsService smsService;@RequestMapping(value="sendLoginVerifyCode", method = RequestMethod.POST)@ApiOperation(value = "sendLoginVerifyCode", notes = "發送登錄短信驗證碼")@ApiImplicitParam(name="paramMap", value = "入參Map", required = true, paramType = "body", dataTypeClass=HashMap.class)public RespBean<Map<String, Object>> sendLoginVerifyCode(@RequestBody Map<String, String> paramMap) {String phoneNumber = paramMap.get("phoneNumber");SendSmsResponse response = smsService.sendLoginVeryCodeMessage(phoneNumber);SendStatus[] statuses = response.getSendStatusSet();Map<String, Object> resultMap = new HashMap<>();resultMap.put("code", statuses[0].getCode());resultMap.put("message", statuses[0].getMessage());resultMap.put("phoneNumber", statuses[0].getPhoneNumber());resultMap.put("fee", statuses[0].getFee());RespBean<Map<String, Object>> respBean = new RespBean<>(200, "success");respBean.setData(resultMap);return respBean;}測試發送短信驗證碼效果
為方便測試,在啟動項目測試發送短信驗證碼接口前我們需要在spring-security配置類WebSecurityConfig中放開對這個接口的攔截
@Overrideprotected void configure(HttpSecurity http) throws Exception {// 配置跨域http.cors().configurationSource(corsConfigurationSource());// 禁用spring security框架的退出登錄,使用自定義退出登錄http.logout().disable();http.authorizeRequests().antMatchers("/user/reg").anonymous().antMatchers("/sendLoginVerifyCode").anonymous()//......省略其他代碼}啟動項目后在postman中測試發送短信驗證碼接口
POST http://localhost:8081/blog/sendLoginVerifyCode {"phoneNumber": "+86-18682244076" }注意發送國內短信時,手機號碼參數前需要加上+86代表地區為中國大陸
點擊postman右上角的Send按鈕響應信息如下, data中的code字段為OK代表發送成功
{"status": 200,"msg": "success","data": {"code": "Ok","phoneNumber": "+8618682244076","fee": 1,"message": "send success"} }手機號碼18682244076的手機上也收到了驗證碼信息:
好了,本文就分享到這里了。本文源碼已上傳到gitee代碼倉庫,倉庫地址:
https://gitee.com/heshengfu1211/blogserver.git
更多有關實現短信功能的使用示例大家可以移步到騰訊云短信服務SDK中心
查看。最后祝所有讀者朋友們都過個紅紅火火、開開心心的大年!
本文首發個人微信公眾號【阿福談Web編程】,歡迎CSDN上的讀者加個微信公眾號關注,讓我們一起在技術的路上前行不孤獨!
下面給騰訊云的新春鉅惠活動產品做個推廣,有需要購買相關騰訊云產品的朋友可以通過下面的鏈接下單
【騰訊云】代金券、域名提前享,更多爆品、新春好禮2月中旬開啟,敬請期待!
【騰訊云】熱門云產品首單特惠秒殺,1核2G云服務器首年38元
【騰訊云】境外1核2G服務器低至2折,半價續費券限量免費領取!
【騰訊云】星星海SA2云服務器,1核2G首年99元起,高性價比首選
【騰訊云】推廣者專屬福利,新客戶無門檻領取總價值高達2860元代金券,每種代金券限量500張,先到先得。
【騰訊云】中小企業福利專場,多款剛需產品,滿足企業通用場景需求,云服務器2.5折起
【騰訊云】云開發CloudBase,一站式高效開發平臺,新用戶選購低至0元
【騰訊云】ElasticSearch新用戶特惠,快速實現日志分析、應用搜索,首購低至4折
【騰訊云】騰訊云數據庫性能卓越穩定可靠,為您解決數據庫運維難題
【騰訊云】騰訊云圖,像PPT一樣簡單的數據可視化工具。5元搞定數據可視化,模板豐富,拖拖拽拽就能做出好看的可視化大屏。
【騰訊云】視頻通信爆款 9.9 元起, 提供電商、教育、社交娛樂等多行業多場景的一站式解決方案,最快 1 天布局火爆賽道
【騰訊云】即時通信 IM 首購 1 折特惠,僅需99.9元/月,支持直播電商、在線教育等多種熱門應用場景
【騰訊云】9.9元體驗2萬分鐘實時音視頻通話,支持1對1或多人音視頻通話,單房可支持300人同時在線,10萬人同時觀看;全平臺互通高品質通話
【騰訊云】云數據庫MySQL基礎版1元體驗,為中小企業量身打造,單節點架構,保證數據可靠性
【騰訊云】專業版APP加固特惠5折起,可享免費兼容性測試
【騰訊云】新客戶首購 TPNS 特惠9.8元/萬 DAU,新老客戶低至6.5折,給您提供快速、穩定、安全、高效的用戶促活利器
總結
以上是生活随笔為你收集整理的SpringBoot项目中快速集成腾讯云短信服务SDK实现手机验证码功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【精华】拒绝国外IP海外IP访问的几种方
- 下一篇: 详细的LaTex语法