阿里雲短信服務(SMS)API 接入教程:支持 Vue SpringBoot
無論是做用戶註冊、登錄驗證,還是訂單狀態通知,短信服務都是剛需。
很多新手看阿里雲官方的短信文檔,容易被一堆 AccessKey、簽名、模板、SDK 概念繞暈,再加上官方示例代碼往往寫得臃腫,一時間不知道怎麼跟自己的前後端項目整合。
今天不扯廢話,直接上實戰。 帶你用最接地氣的「真人寫作風格」,
5分鐘跑通阿里雲短信服務(SMS)從後台配置,到後端 Spring Boot 核心邏輯封裝,再到前端 Vue 的完整倒計時實現。
核心交互流程
在寫代碼之前,先腦補一下驗證碼短信的閉環邏輯:
純文字
【Vue 前端】 ── 1. 輸入手機號,點髮送 ──> 【Spring Boot 後端】
▲ │
│ 2. 生成 6 位隨機數
│ 3. 存入 Redis(設置5分鐘過期)
│ 4. 調用阿里雲 API 發送
│ │
│ ▼
【用戶手機】 <─── 5. 收到短信驗證碼 ───── 【阿里雲短信網關】
第一步:阿里雲控制台開通與資質申請(2分鐘)
由於國內防詐騙治理非常嚴格,短信服務
必須先申請資質和簽名
,直接去調用 API 會報權限錯誤。
1. 開通服務
登錄阿里雲控制台,搜索
「短信服務」
,點擊開通(開通免費,發送按條扣費,建議順手買個幾十塊錢的套餐包)。
2. 申請短信簽名(你是誰)
進入短信服務控制台,左側點擊 「國內消息」 $\rightarrow$ 「簽名管理」 $\rightarrow$ 「添加簽名」。
簽名名稱:通常是你的網站名、APP名或公司簡稱(如 極客博客)。
簽名來源:個人開發者一般選「已備案網站」或「真實應用」,需要提供
你的 ICP 備案號 或應用截圖。
3. 申請短信模板(你發的是什麼)
切換到 「模板管理」 $\rightarrow$ 「添加模板」。
模板類型:選擇 「驗證碼」。
模板名稱:如 登錄驗證碼。
模板內容:固定格式,變量用 ${code} 表示。 例如:您正在登錄系統,驗證碼為:${code},5分鐘內有效,請勿洩露給他人。
提交審核,通常 10~ 30 分鐘就能通過。 記住通過後的 TemplateCode(如 SMS_1234567)。
第二步:後端 Spring Boot 核心對接(3分鐘)
不要用老舊的舊版 SDK 了,我們直接採用阿里雲最新的
V2.0
雲原生 Java SDK,代碼更精簡。
1. 引入 Maven 依賴
在你的 Spring Boot 項目
pom.xml
中引入阿里雲短信核心庫:
XML
<依賴>
<GroupId>com.aliyun</groupId>
<ArtifactId>dysmsapi20170525</artifactId>
<Version>3.0.0</version> </dependency>
2. 在 application.yml 中配置密鑰
還記得我們上一期講過的 RAM 最小權限原則嗎? 去阿里雲 RAM 控制台建一個子賬號,只賦予
AliyunDysmsFullAccess
(短信管理)權限,生成一組 AK/SK 填在這裡:
YAML
Aliyun:
Sms:
Access-key-id: LTAI5tXXXXXXXXXXXX # 子賬號AK
Access-key-secret: Pn7yXXXXXXXXXXXXXXXX # 子賬號SK
Sign-name: 極客博客 # 你申請通過的簽名
Template-code: SMS_1234567 # 你申請通過的模板ID
3. 封裝短信發送工具類
創建一個 Service,直接複製下面我為你精簡優化後的純乾貨代碼:
Java
Import com.aliyun.dys
Msapi20170525.Client;
Import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
Import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
Import com.aliyun.teaopenapi.models.Config;
Import org.springframework.beans.factory.annotation.Value;
Import org.springframework.stereotype.Service;
@Service
Public class SmsService {
@Value("${aliyun.sms.access-key-id}")
Private String accessKeyId;
@Value("${aliyun.sms.access-key-secret}")
Private String accessKeySecret;
@Value("${aliyun.sms.sign-name}")
Private String signName;
@Value("${aliyun.sms.template-code}")
Private String templateCode;
/**
* 發送驗證碼短信
* @Param phone 目標手機號
* @Param code 隨機驗證碼
*/
Public boolean sendVerifyCode(String phone, String code) {
嘗試 {
// 1. 初始化配置客戶端
Config config = new Config()
. SetAccessKeyId(accessKeyId)
. SetAccessKeySecret(accessKeySecret);
// 固定的短信服務接入點
Config.endpoint = "dysmsapi.aliyuncs.com";
Client client = new Client(config);
// 2. 組裝請求參數
SendSmsRequest request = new SendSmsRequest()
. SetPhoneNumbers(phone)
. SetSignName(signName)
. SetTemplateCode(templateCode)
// 變量必須轉成 JSON 字符串格式
. SetTemplateParam("{\"code\":\"" code "\"}");
// 3. 執行發送
SendSmsResponse response = client.sendSms(request);
// 4. 判斷發送結果
If ("OK".equals(response.getBody().getCode())) {
Return true;
} Else {
System.err.println("短信發送失敗,原因: " response.getBody().getMessage());
Return false;
}
} Catch (Exception e) {
E.printStackTrace();
Return false;
}
}
}
4. 編寫 Controller 業務接口
在 Controller 層,結合你的 Redis(這裡用偽代碼代替展示邏輯閉環):
Java
@RestController
@RequestM
Apping("/api/sms")
Public class SmsController {
@Autowired
Private SmsService smsService;
@Autowired
Private StringRedisTemplate redisTemplate; // 注入Redis
@PostMapping("/send")
Public ResponseEntity<String> sendCode(@RequestParam String phone) {
// 1. 簡易手機號正則校驗
If (! Phone.matches("^1[3-9]\\d{9}$")) {
Return ResponseEntity.badRequest().body("手機號格式不正確");
}
// 2. 防刷機制:檢查 Redis 確定 60 秒內沒有重複發送
If (Boolean.TRUE.equals(redisTemplate.hasKey("SMS_LIMIT:" phone))) {
Return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("發送太頻繁,請稍後再試");
}
// 3. 生成 6 位隨機數驗證碼
String code = String.valueOf((int)((Math.random() * 9 1) * 100000));
// 4. 調用阿里雲服務發送
Boolean isSuccess = smsService.sendVerifyCode(phone, code);
If (! IsSuccess) {
Return ResponseEntity.status(500).body("短信發送失敗,請聯繫管理員");
}
// 5. 存入 Redis,設置 5 分鐘有效期;同時設置一
個 60 秒的防刷限制
RedisTemplate.opsForValue().set("SMS_CODE:" phone, code, 5, TimeUnit.MINUTES);
RedisTemplate.opsForValue().set("SMS_LIMIT:" phone, "1", 60, TimeUnit.SECONDS);
Return ResponseEntity.ok("驗證碼發送成功");
}
}
第三步:前端 Vue 倒計時組件編寫(1分鐘)
後端搞定了,前端我們要防範用戶狂點「發送」按鈕,需要做一個標準的 60 秒倒計時。
這裡以
Vue 3 (Composition API) Axios
為例,直接上最直觀的代碼:
代碼段
<Template>
<Div class="sms-box">
<Input type="text" v-model="phone" placeholder="請輸入手機號" />
<Button :disabled="isCounting" @click="handleSend">
{{ IsCounting ? '${Countdown}秒後重新獲取' : '獲取驗證碼' }}
</Button>
</div>
</Template>
<script setup>
Import { ref } from 'vue';
Import axios from 'axios';
Const phone = ref('');
Const countdown = ref(60);
Const isCounting = ref(false);
Let timer = null;
Const handleSend = async () => {
如果! /^1[3-9]\d{9}$/.test(phone.value)) {
Alert('請輸入正確的手機號');
返回;
}
嘗試 {
// 調用後端接口
Const res = awa
It axios.post('/api/sms/send? Phone=${phone.value}');
Alert(res.data);
// 激活倒計時
StartCountdown();
} 捕捉 (錯誤) {
Alert(error.response?. Data || '請求失敗');
}
};
Const startCountdown = () => {
IsCounting.value = true;
Countdown.value = 60;
Timer = setInterval(() => {
Countdown.value--;
If (countdown.value <= 0) {
ClearInterval(timer);
IsCounting.value = false;
}
}, 1000);
};
</Script>
生產環境避坑指南(運維血淚經驗)
小心接口被黑客「短信轟炸」! 接口一上線,黑客就會用自動化腳本拿著幾萬個隨機手機號來瘋狂請求你的 /api/sms/send 接口。 一晚上就能把你的阿里雲賬戶餘額全扣光。 鐵律防禦:除了前端做 60 秒倒計時、後端用 Redis 限制單手機號 60 秒頻率之外,針對發送短信的接口,必須強行加上「圖形驗證碼」或「人機滑塊驗證」。 只有拼圖成功的合法請求,後端才發短信。
觸發阿里雲的「頻次限制」報錯阿里雲短信官方自帶了一套流控防刷機製(單手機號 1 分鐘內不超過 1 條,1 小時內不超過 5 條,1 天內不超過 10 條)。 如果你本地測試時瘋狂給自己發短信,突然報錯 isv.BUSINESS_LIMIT_CONTROL,別慌,不是代碼寫錯了,是你被阿里雲官方限流了,明天會自動解封。
這一套前後端閉環走下來,你的微服務應用就正式具備了合規、安全的短消息通知能力。 趕快部署去試試看吧!
