目前在很多项目中都出现使用短信验证码来实现注册、登录、购买、支付、转账等功能,发短信功能几乎已经成为项目中不可或缺的技术之一。
短信平台与运营商之间协同合作,利益分成。
短信发送流程通常涉及以下步骤:
需要注意的是,由于短信平台和运营商之间的协议和接口是不透明的,因此在实际使用中,需要根据具体的短信平台和运营商提供的文档和接口规范来实现短信发送功能。同时,也需要根据运营商的要求和规定进行短信内容的审核和审核通过后的定时发送等操作。
这里只针对于
国内短信验证码
进行说明。
开通服务是免费的,短信套餐包可购买也可选择试用。
新用户试用地址:阿里云通信产品免费试用 (aliyun.com)
普通用户购买地址:短信服务_企业短信营销推广_验证码通知-阿里云 (aliyun.com)
短信服务 (aliyun.com)
短信模版内容是由国家工信部制定,模版内容必须得有国家工信部进行审核,短信模版包含两部分:
公共内容规范 (aliyun.com)
短信签名规范 (aliyun.com)
说明几个重要通知:
公众号或小程序
,暂不支持以个人名义认证的小程序或公众号。测试或学习
,发送会有限制,指的是不能申请带变量的通知模板,不能申请推广模板,且只能给绑定的手机号发送短信。您可以参考下表示例,并根据实际业务需求创建符合规范的短信模板。
应用场景 | 模板示例 |
---|---|
登录/验证 | 您的验证码${code} ,该验证码5分钟内有效,请勿泄漏于他人!您的验证码: ${code} ,您正进行身份验证,打死不告诉别人!验证码为: ${code} ,您正在登录,若非本人操作,请勿泄露。 |
注册 | 您正在申请手机注册,验证码为:${code} ,5分钟内有效!尊敬的用户,您的注册会员动态密码为: ${code} ,请勿泄漏于他人!您的注册码: ${code} ,如非本人操作,请忽略本短信!您的校验码: ${code} ,您正在注册成为会员,感谢您的支持!验证码为: ${code} ,您正在注册成为平台会员,感谢您的支持! |
重置密码 | 您的动态码为:${code} ,您正在进行密码重置操作,如非本人操作,请忽略本短信! |
变更信息 | 验证码为:${code} ,您正在尝试变更重要信息,请妥善保管账户信息。 |
根据短信的发送条数和短信模板类型进行实时梯度计费。即实时计费,自动跨档,跨档后当月所有发送量按新阶梯价重新计算。
验证码
、短信通知
、推广短信
三种类型。个人认证用户仅可使用验证码、短信通知,不可使用推广短信。您可以升级为企业认证用户体验相关功能。更多信息,请参见使用须知。套餐包的具体计费,请参见国内通用短信套餐包。
**短信长度(字数)=短信签名字数+短信模板内容字数。**其中,短信模板字数上限为500字。
简体中文、字母、数字、标点符号(不区分全角和半角),都按照一个字计算。
为避免与签名混淆,在模板内容任意位置均不能使用【】,在模板内容首尾不能使用[ ]。
短信长度不超过70个字,按照一条短信计费;超过70个字,即为长短信,按照67字/条拆分成多条计费。
示例:短信长度为160个字,按照67字、67字、26字分隔成三条短信进行计费。
在实际业务场景中,例如App或网站登录时,可能会有用户频繁获取短信验证码或者通过短信通知方式找回密码的操作。为了限制平台短信被恶意调用、在短时间内大量发起短信发送请求,阿里云对短信发送验证码的行为进行了流控限制。
注意这个 AccessKey ID
和 AccessKey Secret
一定要保存下来,后面需要使用并且关闭该页面后无法再获取 AccessKey Secret
。
我们在这里只添加 短信服务 的权限。
前提条件:
- 完成阿里云账号注册和实名认证。
- 开通短信服务。
这里以签名来源为测试或学习
进行演示,并注意 个人认证用户限申请一个验证码签名,一个自然日只能申请一个通用签名。如需申请多个签名,建议升级为企业认证用户。
通着这个需要两三小时左右,因此等这一步被通过了再进行接下来的操作。
通着这个需要两三小时左右,因此等这一步被通过了再进行接下来的操作。
由于我们这里指定的短信签名来源是测试或学习
,因此只有绑定了的手机号才能收到短信消息。
查看绑定的手机,可以接受到消息:
将 8.在线测试签名模板API 中屏幕右边的代码进行拷贝自己运行即可:
<dependency>
<groupId>com.aliyungroupId>
<artifactId>alibabacloud-dysmsapi20170525artifactId>
<version>2.0.23version>
dependency>
// This file is auto-generated, don't edit it. Thanks.
package demo;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.dysmsapi20170525.models.*;
import com.aliyun.sdk.service.dysmsapi20170525.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;
//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class SendSms {
public static void main(String[] args) throws Exception {
// HttpClient Configuration
/*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
.connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
.responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
.maxConnections(128) // Set the connection pool size
.maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
// Configure the proxy
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("", 9001))
.setCredentials("", ""))
// If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
.x509TrustManagers(new X509TrustManager[]{})
.keyManagers(new KeyManager[]{})
.ignoreSSL(false)
.build();*/
// Configure Credentials authentication information, including ak, secret, token
StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
.accessKeyId("" )
.accessKeySecret("" )
//.securityToken("") // use STS token
.build());
// Configure the Client
AsyncClient client = AsyncClient.builder()
.region("cn-wulanchabu") // Region ID
//.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
.credentialsProvider(provider)
//.serviceConfiguration(Configuration.create()) // Service-level configuration
// Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
.overrideConfiguration(
ClientOverrideConfiguration.create()
.setEndpointOverride("dysmsapi.aliyuncs.com")
//.setConnectTimeout(Duration.ofSeconds(30))
)
.build();
// Parameter settings for API request
SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
.signName("逐浪教育")
.templateCode("SMS_275395309")
.phoneNumbers("18670082846")
.templateParam("{\"code\":\"1234\"}")
// Request-level configuration rewrite, can set Http request parameters, etc.
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
.build();
// Asynchronously get the return value of the API request
CompletableFuture<SendSmsResponse> response = client.sendSms(sendSmsRequest);
// Synchronously get the return value of the API request
SendSmsResponse resp = response.get();
System.out.println(new Gson().toJson(resp));
// Asynchronous processing of return values
/*response.thenAccept(resp -> {
System.out.println(new Gson().toJson(resp));
}).exceptionally(throwable -> { // Handling exceptions
System.out.println(throwable.getMessage());
return null;
});*/
// Finally, close the client
client.close();
}
}
sms:
ali:
# 子用户的访问键
accessKeyId: LTAI5tPBmf8y7ZoQSn9h****
# 子用户的访问密钥
accessKeySecret: cbd511ed24bd832d05af54f64c84****
# 签名名称
signName: 逐浪教育
# 登录短信模板的code
loginTemplateCode: SMS_27539****
就是在 4.3 创建子用户
中得到的 accessKeyId 与 accessKeySecret
就是在 5.添加签名
中设置的签名内容。
由于demo代码过多,这里不做展示。
实战demo源码地址:Mr-Write/SpringbootDemo: 各种demo案例 (github.com)
对应的是 sms-demo
包模块。
示例演示,用 Apipost7 进行测试:【POST】 http://127.0.0.1:10505/sms-ali/sendLoginCode
同时在我的手机上也接受到了验证码消息。
名称 | 类型 | 描述 | 示例 |
---|---|---|---|
Code | String | 请求状态码。返回OK代表请求成功。其他错误码,请参见[API错误码](https://help.aliyun.com/document_detail/101346.html?spm=api-workbench.API Document.0.0.5be349a5PlzN8a)。 | OK |
Message | String | 状态码的描述。 | OK |
BizId | String | 发送回执ID。可根据发送回执ID在接口QuerySendDetails中查询具体的发送状态。 | 9006197469364984**** |
RequestId | String | 请求ID。 | F655A8D5-B967-440B-8683-DAD6FF8DE990 |
正常返回的JSON格式示例
{
"Code": "OK",
"Message": "OK",
"BizId": "9006197469364984****",
"RequestId": "F655A8D5-B967-440B-8683-DAD6FF8DE990"
}
安装需要的包
sudo apt-get update
安装依赖包
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
设置远程仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
安装 Docker-CE
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
验证是否成功
sudo docker run hello-world
# 拉取redis镜像
docker pull redis
# 启动容器的时候,并为其设置密码
docker run -d --name myredis -p 6379:6379 redis --requirepass "123456"
注意需要将服务器防火墙6379端口打开。