TEL:15503997879
在CSDN博客中也有人写过关于asp阿里云短信的文章,在这里本人通过一段时间的研究,也完成了asp调用阿里云的短信验证码服务的功能,在此总结一下,服务的主要内容在于签名的生成,以及相关的http请求的地址生成。其中细节性的东西还是非常多的,因为阿里云API文档中只有java,php,asp.net,python,node等版本,没有关于asp的相关说明,对签名的时间戳、随机数(UUID)、参数拼接、参数排序及参数编码签名。
下面针对asp说明完成步骤,仅供参考。
1、获取AccessKey https://help.aliyun.com/document_detail/53045.html?parentId=44282
2、创建UUID
Function GetRndCode()
Dim objTypeLib
Set objTypeLib = CreateObject("Scriptlet.TypeLib")
strSignatureNonce=cstr(mid(objTypeLib.Guid, 2 ,len(objTypeLib.Guid)-4))
GetRndCode = LCase(strSignatureNonce)
End Function
3、请求的时间戳
Function FormatDate(sDateTime, sReallyDo)
Dim sJorkin
sJorkin = GetLocale()
If Not IsDate(sDateTime) Then sDateTime = Now()
sDateTime = CDate(sDateTime)
Select Case UCase(sReallyDo & "")
Case "0", "1", "2", "3", "4"
FormatDate = FormatDateTime(sDateTime, sReallyDo)
Case "00"
FormatDate = FormatDate(sDateTime, "YYYY-MM-DD hh:mm:ss")
Case "01"
FormatDate = FormatDate(sDateTime, "YYYY年MM月DD日")
Case "02"
FormatDate = FormatDate(sDateTime, "YYYY-MM-DD")
Case "03"
FormatDate = FormatDate(sDateTime, "hh:mm:ss")
Case "04"
FormatDate = FormatDate(sDateTime, "hh:mm")
Case "ISO8601", "GOOGLE", "SITEMAP" '//ISO8601格式, 一般用于GoogleSiteMap, "+08:00" 为时区.
FormatDate = FormatDate(sDateTime, "YYYY-MM-DDThh:mm:ss.000+08:00")
Case "RFC822", "RSS", "FEED" '//RFC822格式, 一般用于RSS, "+0800" 为时区.
SetLocale("en-gb")
FormatDate = FormatDate(sDateTime, "ew, DD eMM YYYY hh:mm:ss +0800")
SetLocale(sJorkin)
Case "RND", "RAND", "RANDOMIZE" '//随机字符串
Randomize
sJorkin = Rnd()
FormatDate = FormatDate(sDateTime, "YYYYMMDDhhmmss") & _
Fix((9 * 10^6 -1) * sJorkin) + 10^6
Case Else
FormatDate = sReallyDo
FormatDate = Replace(FormatDate, "YYYY", Year(sDateTime))
FormatDate = Replace(FormatDate, "DD", Right("0" & Day(sDateTime), 2))
FormatDate = Replace(FormatDate, "hh", Right("0" & Hour(sDateTime), 2))
FormatDate = Replace(FormatDate, "mm", Right("0" & Minute(sDateTime), 2))
FormatDate = Replace(FormatDate, "ss", Right("0" & Second(sDateTime), 2))
FormatDate = Replace(FormatDate, "YY", Right(Year(sDateTime), 2))
FormatDate = Replace(FormatDate, "D", Day(sDateTime))
FormatDate = Replace(FormatDate, "h", Hour(sDateTime))
FormatDate = Replace(FormatDate, "m", Minute(sDateTime))
FormatDate = Replace(FormatDate, "s", Second(sDateTime))
If InStr(1, FormatDate, "EW", 1) > 0 Then
SetLocale("en-gb")
FormatDate = Replace(FormatDate, "EW", UCase(WeekdayName(Weekday(sDateTime), False)))
FormatDate = Replace(FormatDate, "eW", WeekdayName(Weekday(sDateTime), False))
FormatDate = Replace(FormatDate, "Ew", UCase(WeekdayName(Weekday(sDateTime), True)))
FormatDate = Replace(FormatDate, "ew", WeekdayName(Weekday(sDateTime), True))
SetLocale(sJorkin)
Else
FormatDate = Replace(FormatDate, "W", WeekdayName(Weekday(sDateTime), False))
FormatDate = Replace(FormatDate, "w", WeekdayName(Weekday(sDateTime), True))
End If
If InStr(1, FormatDate, "EMM", 1) > 0 Then
SetLocale("en-gb")
FormatDate = Replace(FormatDate, "EMM", MonthName(Month(sDateTime), False))
FormatDate = Replace(FormatDate, "eMM", MonthName(Month(sDateTime), True))
SetLocale(sJorkin)
Else
FormatDate = Replace(FormatDate, "MM", Right("0" & Month(sDateTime), 2))
FormatDate = Replace(FormatDate, "M", Month(sDateTime))
End If
End Select
End Function
调用方法
"Timestamp="&FormatDate(dateadd("h",-8,now()),"02")&"T"&server.urlencode(FormatDate(dateadd("h",-8,now()),"03"))&"Z"
以上就是调用接口时需要创建的公共请求参数获取方法。发送短信时需要请求签名,在说一下签名的注意事项。
1、创建签名参数组
function createParamsArr()
params_KeyId = "AccessKeyId=自己申请的AccessKey"
params_Action = "Action=SendSms"
params_Format = "Format=JSON"
params_RegionId = "RegionId=cn-hangzhou"
params_Method = "SignatureMethod=HMAC-SHA1"
params_Nonce = "SignatureNonce=调用上面的UUID"
params_SVersion = "SignatureVersion=1.0"
params_Timestamp = "Timestamp="&FormatDate(dateadd("h",-8,now()),"02")&"T"&server.urlencode(FormatDate(dateadd("h",-8,now()),"03"))&"Z" '参见上面的方法描述
params_Version = "Version=2017-05-25"
params_OutId = "OutId=123"
params_Phone = "PhoneNumbers=发送手机号"
params_SignName = "SignName=abcd" 'abcd 是阿里云国内文本短信中的签名
params_TemplateParam = "TemplateParam=12345" '12345是阿里云国内文本短信中的模板名称
params_TemplateCode ="TemplateCode=sms_123456" 'sms_123456阿里云国内文本短信中的模板CODE
createParamsArr =array(params_Method,params_KeyId,params_Nonce,params_SVersion,params_Timestamp,params_Format,params_Action,params_Version,params_RegionId,params_Phone,params_SignName,params_TemplateParam,params_TemplateCode,params_OutId)
end function
2、对签名参数组排序
Function Sortarray(ary)
Dim KeepChecking,I,FirstValue,SecondValue
KeepChecking=TRUE
Do Until KeepChecking=FALSE
KeepChecking=FALSE
For I=0 to UBound(ary)
If I=UBound(ary) Then Exit For
If ary(I)>ary(I+1) Then
FirstValue=ary(I)
SecondValue=ary(I+1)
ary(I)=SecondValue
ary(I+1)=FirstValue
KeepChecking=TRUE
End If
Next
Loop
Sortarray=ary
End Function
3、生成签名用的拼接参数
function createSign(params_arr_sign)
for i = 0 to ubound(params_arr_sign)
temp = params_arr_sign(i)
if instr(temp,"SignName") >= 1 or instr(temp,"TemplateParam")>= 1 then
temp = server.urlencode(temp) '此处是个坑,需要注意,签名时此处做了两次urlencode
temp = replace(temp,"%3D","=")
end if
if i=0 Then
params_str = temp
else
params_str = params_str & "&"& temp
end if
next
params_str= replace(replace(replace(server.urlencode(params_str),"%2D","-"),"%2E","."),"%5F","_")
params_str = "GET&" & server.urlencode("/") & "&" & params_str
key= accessSecret & "&" '此处为api文档中在accessSecret 后加一个&做密钥用
message = params_str
response.write params_str '此处就是签名用的字符串
'--以下为核心签名编码部分----
1、对key 做utf8 处理 pakey2=Utf8处理(key)
2、获得hmacsha1结果后,再做16进制转换 pure_hash=BinToHex(HmacSha1(message,pakey2))
3、对pure_hash进行Base64编码,获得最终的签名结果,并对结果进行URLEncode处理。这里的base64等同于js版本的 CryptoJS.enc.Base64,计算方式https://1024tools.com/hmac 中的结果B 如有需要请联系tel:15503997879 微信同号
createSign = server.URLEncode(Base64(Hex(pure_hash)))
end function
4、通过参数数组URL
function createParamsUrl(params_arr_url,params_arr_sign)
params_url ="http://dysmsapi.aliyuncs.com/?Signature=" &createSign(params_arr_sign)
for i = 0 to ubound(params_arr_url)
params_url = params_url &"&" & params_arr_url(i)
next
createParamsUrl = params_url
'response.write createParamsUrl &"<br>"
end function
5、Get方法请求url,获取请求内容
Function RequestUrl(url)
Set XmlObj = Server.CreateObject("Microsoft.XMLHTTP")
XmlObj.open "GET",url, false
XmlObj.send
RequestUrl = XmlObj.responseText
Set XmlObj = nothing
End Function
function send_sms()
params_arr = createParamsArr()
params_arr_sign = Sortarray(params_arr) '签名用'
params_arr_url = FilterPara(params_arr_sign) '传参用
response.write RequestUrl(createParamsUrl(params_arr_url,params_arr_sign))
end function
6、我的结果是:{"RequestId":"B5CA0DD1-F36B-52AC-BD83-59070A5B4BD9","Message":"账户余额不足","Code":"isv.AMOUNT_NOT_ENOUGH"} 。哈哈!!