Delphi开发短信应用-阿里云服务

目录

 

Delphi开发短信应用-阿里云服务

一、阿里云短信、语音、流量API接口

1.1、入参列表

短信Rest请求参数:

短信输入参数:

1.2、出参列表

1.3、Rest响应错误码列表

1.4、基于Node.js的SDK代码demo参考及说明

二、Delphi实现阿里云短信的关键-签名算法的实现

2.1、第一步:请求参数:

2.2、 第二步:根据参数Key排序(顺序):

2.3、 第三步:构造待签名的请求串:

2.4、 第四步:阿里云专用签名:

2.5、 第五步:增加签名结果到请求参数中,发送请求:

三、用Delphi通用Rest类及其方法发送阿里云短信


 

 

Delphi开发短信应用-阿里云服务

以此文作为参考,开发者可以开发任何云平台上V3版的Rest API接口的服务应用。

一、阿里云短信、语音、流量API接口

云通信下的三类产品(包括短信、语音、流量),Rest API接口协议一致:

https://help.aliyun.com/document_detail/56189.html?spm=a2c4g.11186623.6.670.f3786220T5zc4h

1.1、入参列表

短信Rest请求参数:

如HTTP示例包中,请求的参数可以分两大块:系统参数和业务参数。
系统参数为POP协议的基本参数:

参数KEY 是否必填 说明
AccessKeyId  
Timestamp 格式为:yyyy-MM-dd'T'HH:mm:ss'Z';时区为:GMT
Format 没传默认为JSON,可选填值:XML
SignatureMethod 建议固定值:HMAC-SHA1
SignatureVersion 建议固定值:1.0
SignatureNonce 用于请求的防重放攻击,每次请求唯一,JAVA语言建议用:java.util.UUID.randomUUID()生成即可
Signature 最终生成的签名结果值

业务参数:

参数KEY 是否必填 说明
Action API的命名,固定值,如发送短信API的值为:SendSms
Version API的版本,固定值,如短信API的值为:2017-05-25
RegionId API支持的RegionID,如短信API的值为:cn-hangzhou
PhoneNumbers 具体见API文档描述
SignName 具体见API文档描述
TemplateCode 具体见API文档描述
TemplateParam 具体见API文档描述
OutId 具体见API文档描述

短信输入参数:

参数名称 参数类型 必填与否 样例取值 参数说明
PhoneNumbers String 必须 15000000000 短信接收号码。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式,发送国际/港澳台消息时,接收号码格式为:国际区号+号码,如“85200000000”。
SignName String 必须 云通信 短信签名。
TemplateCode String 必须 SMS_0000 短信模板ID,发送国际/港澳台消息时,请使用国际/港澳台短信模版。
TemplateParam String 可选 {"code":"1234","product":"ytx"} 短信模板变量替换JSON串,友情提示:如果JSON中需要带换行符,请参照标准的JSON协议要求。
OutId String 可选 abcdefgh 外部流水扩展字段。

1.2、出参列表

 
出参名称 出参类型 样例取值 参数说明
RequestId String 8906582E-6722 请求ID。
Code String OK 状态码。返回OK代表请求成功,其他错误码详见错误码列表。
Message String 请求成功 状态码的描述。
BizId String 134523^4351232 发送回执ID,可根据该ID查询具体的发送状态。

1.3、Rest响应错误码列表

 
Code 描述
OK 请求成功。
isp.RAM_PERMISSION_DENY RAM权限DENY。
isv.OUT_OF_SERVICE 业务停机。
isv.PRODUCT_UN_SUBSCRIPT 未开通云通信产品的阿里云客户。
isv.PRODUCT_UNSUBSCRIBE 产品未开通。
isv.ACCOUNT_NOT_EXISTS 账户不存在。
isv.ACCOUNT_ABNORMAL 账户异常。
isv.SMS_TEMPLATE_ILLEGAL 短信模板不合法。
isv.SMS_SIGNATURE_ILLEGAL 短信签名不合法。
isv.INVALID_PARAMETERS 参数异常。
isp.SYSTEM_ERROR 系统错误。
isv.MOBILE_NUMBER_ILLEGAL 非法手机号。
isv.MOBILE_COUNT_OVER_LIMIT 手机号码数量超过限制。
isv.TEMPLATE_MISSING_PARAMETERS 模板缺少变量。
isv.BUSINESS_LIMIT_CONTROL 业务限流。
isv.INVALID_JSON_PARAM JSON参数不合法,只接受字符串值。
isv.BLACK_KEY_CONTROL_LIMIT 黑名单管控。
isv.PARAM_LENGTH_LIMIT 参数超出长度限制。
isv.PARAM_NOT_SUPPORT_URL 不支持URL。
isv.AMOUNT_NOT_ENOUGH 账户余额不足。

1.4、基于Node.js的SDK代码demo参考及说明

https://help.aliyun.com/document_detail/57458.html?spm=a2c4g.11186623.6.687.7e9e2e7ev2MlSn

二、Delphi实现阿里云短信的关键-签名算法的实现

阿里云短信的POP签名算法

https://help.aliyun.com/document_detail/56189.html?spm=a2c4g.11186623.6.670.f3786220T5zc4h

见其中的【2.3 生成签名】 的说明。签名是为了让请求合法,共分为五步:

2.1、第一步:请求参数:

请求参数包括系统参数和业务参数,不要遗漏
请求参数中不允许出现以Signature为key的参数。 参考代码如下:

var  Params: TDictionary<string, string>;  SortedParams: TArray<string>;
     LParamIndex :Integer; 
//①.系统参数:
    Params.Add('AccessKeyId', AccessKeyId);
    Params.Add('Timestamp', GetTimestamp);
    Params.Add('Format', 'JSON');
    Params.Add('SignatureMethod', 'HMAC-SHA1');
    Params.Add('SignatureNonce',
      THashMD5.GetHashString(TGUID.NewGuid.ToString));
    Params.Add('SignatureVersion', '1.0');
//②.业务API参数:
    Params.Add('Action', 'SendSms');
    Params.Add('Version', '2017-05-25');
    Params.Add('RegionId', 'cn-hangzhou');
    Params.Add('PhoneNumbers', PhoneNumbers);
    Params.Add('SignName', SignName);
    Params.Add('TemplateCode', TemplateCode);
    Params.Add('TemplateParam', TemplateParam);
    Params.Add('OutId', '');

//③.去除签名关键字Key:
    //2.1.3:(我加的严格按照API说明更安全)去除签名关键字Key:'Signature':
    if Params.ContainsKey('Signature') then Params.Remove('Signature');

2.2、 第二步:根据参数Key排序(顺序):

    //2.2、第二步:根据参数Key排序(顺序)::
    SortedParams := Params.keys.ToArray;
    TArray.Sort<string>(SortedParams);

2.3、 第三步:构造待签名的请求串:

构造待签名的请求串这里有两步动作:

2.3.1、POP的URL编码特殊字符替换
第1步,把排序后的各参数按顺序拼接成如下格式的字符串sortQueryString
"&" specialUrlEncode(参数Key) + "=" + specialUrlEncode(参数值)

    首先介绍下面会用到的特殊URL编码 这个是POP特殊的一种规则,即在一般的URLEncode后再增加三种字符替换:加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~) 参考代码如下:

// POP的URL编码特殊字符替换参考代码如下:
  function SpecialUrlEncode(const Value: string): string;
  // SendVerificationCodeBySMS专用
  begin
    Result := TNetEncoding.URL.Encode(Value).Replace('+', '%20')
      .Replace('*', '%2A').Replace('%7E', '~');
  end;

2.3.2、拼接sortQueryString

      sortQueryString:='';  LParamIndex:=0;
      for Key in SortedParams do
      begin
        if LParamIndex=0 then
          sortQueryString:=sortQueryString
            +SpecialUrlEncode(Key)
            +'='+SpecialUrlEncode(Params.Items[Key])
        else
          sortQueryString:=sortQueryString
            +'&'+SpecialUrlEncode(Key)
            +'='+SpecialUrlEncode(Params.Items[Key]);
        INC(LParamIndex);
        //:第1个参数不带连接符&
      end;

2.4、 第四步:阿里云专用签名:

签名采用HmacSHA1算法 + Base64,编码采用:UTF-8 ,官方Java函数:

String sign = sign(accessSecret + "&", stringToSign.toString());

特别说明:POP要求需要后面多加一个“&”字符,即accessSecret + “&” 

2.4.1、Delphi的HmacSHA1算法函数

THashSHA1.GetHMACAsBytes

2.4.2、Delphi的Base64函数

TNetEncoding.Base64.EncodeBytesToString

2.4.3、构造阿里云专用Delphi签名函数

  function Sign(const AData, Key: string): string;
  var
    HashBytes: TBytes;
  begin
    HashBytes := THashSHA1.GetHMACAsBytes(AData, Key);
    Result := TNetEncoding.Base64.EncodeBytesToString(HashBytes);
  end;

调用:

AcessSecret:你的AccessKeyId对应的秘钥AccessSecret

Signature := Sign(sortQueryString,AccessKeySecret + '&');

签名后的结果类似打印如下:

zJDF+Lrzhj/ThnlvIToysFRq6t4=	

2.5、 第五步:增加签名结果到请求参数中,发送请求

注意 :上步骤最后一小步,签名也要做POP的URL编码特殊字符替换:

//String Signature = specialUrlEncode(sign);// zJDF%2BLrzhj%2FThnlvIToysFRq6t4%3D
:Delphi代码如下:
Signature := SpecialUrlEncode(Signature);
zJDF+Lrzhj/ThnlvIToysFRq6t4=	
POP的URL编码特殊字符替换后:
zJDF%2BLrzhj%2FThnlvIToysFRq6t4%3D

签名完毕!

三、用Delphi通用Rest类及其方法发送阿里云短信

参考本博客博文:

delphi Restful:客户端实现的四种方式及其比较

喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/113997246