哪位大神,短信接口使用的是阿里云的短信验证平台

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了哪位大神,短信接口使用的是阿里云的短信验证平台相关的知识,希望对你有一定的参考价值。

首先了解一下短信验证码的目的和应用场景:

短信验证码的目的一是为了绑定用户,二是和用户建立一种直接的沟通途径,三是便捷登录。应用方式有动态密码,手机验证码;应用场景APP或网站系统等。

选择一家靠谱的短信验证平台也要考虑到三方面和三个指标:
第一方面服务怎么样?
好的服务不仅仅是让你合作起来很放心,而且出现问题了能及时的解决减少因此带来的利益损失。
第二方面,平台技术能力怎么样?
小数据量及小的并发一般平台都能承载,但是如果一天高达亿万级的数据量,并发5000条/秒,这就是对技术实力的考验,技术能力弱的平台可能直接就死掉了,直接影响到客户。
第三方面是价格,通常短信验证码的价格是依据用户发送量来定的,量越多价格越有优惠,一分价格一分货的东西,只要不是砍价太过分短信平台一般也不会用质量差的通道给你走。

验证码短信考核指标三方面,及时性、到达率、稳定性。

另外有实力的短信平台通道资源比较丰富,不会出现那么多的屏蔽地区和屏蔽号码,短信验证码服务没有地域性的限制,不是地区越速度就越快,服务就很好,互联网公司拼的就是技术和服务。

需要注意的是验证码通常是用在注册或登录类的身份验证,如果用户是注册类的,当验证码接收不到将会损失直接客户,这个客户一旦流失到竞争对方那边,不但壮大对手削弱自己。

现在网上大家很多在问为什么不用阿里短信,在此通过网络收集整理了以下几点认为比较在意的:
(1)阿里报备签名必须是公司字号或商标名,这点受限比较多;
(2)会员营销类的信息在阿里在一旦遭到手机用户投诉就会锁帐号;
(3)阿里内容要求比较严格;
(4)阿里只支持纯技术对接,没有自己可以登录的界面发送、查询、统计等功能;
(5)如果有问题要咨询或解决,没有人工客服这点很是不方便,效率会低些;
(6)阿里价格优势不大。

短信验证码属于企业基础服务,巴卜短信在这块作的比较专业而且在这个行业内的口碑也不错,他们不仅仅有短信验证码也支持语音验证码和国际短信验证码可以满足不用的应用场景和环境,对接时他们会提供接口文档和示例代码,对接十分简捷。

最后再次提醒不要贪图便宜选择价格过低的通道资源,价格低了,随之带来的损失就是丢失客户,一条短信没有收到,和节约一两厘的成本。就短信费用而言,就是直接几十倍的差距。丢失的客户的损失会更大,现在互联网公司获客成本高达几十元一位,这种因几厘的差距,造成更大的损失得不偿失。

.

.

1、接触不良(1、检查数据线连接的插头是否插紧,把螺丝拧紧一点 2、检查一下数据线的针是否有歪提的

,插拔姿势不对会弄歪数据线 )
2、显示器老化会造成聚焦不准
3、显卡问题,(排除了问题1和后,换条数据线或换台显示器,看是否依然有问题)如有的话,基本可以判断是显卡针孔问题


参考技术A 阿里短信提供HTTP等协议接口可供您调用。
发送验证码信息并不一定只有阿里去短信可以发送。如果您发送的内容中有签名不是固定一个,也不是你们公司的字号名,或商标名,阿里就不允许您使用。

现在大公司的平台系统都集成了短信验证码、短信预警和异常报错短信通知模板,您的这种作法是完全可性的,有关作短信预警的短信平台,除了您所说的阿里外您也可以考虑一下巴卜短信,他们为很多CRM,MIS,ERP等系统作短信支持,他们也许不仅仅提供短信服务还能提供解决方案。希望我的回答能帮到您。
参考技术B 国内这样的公司有很多,短信验证码是基于第三方技术支持,有平台式和嵌入式。像超市给客户发促销活动就是平台,物流签收短信就是嵌入式,上网搜“短信验证码”首页第5个。M 参考技术C 阿里云的短信验证接口是接的其他的短信平台,在万商超信就与其合作 参考技术D 凌凯的短信验证码接口到达率在五秒之内

使用阿里云的短信服务发送短信

在给客户开发一个信息发送功能的时候,需要涉及到短信的发送,短信发送一般不同的厂商提供的接口不同,处理方式也不太一样,之前用的一个厂商的,提供了一个封装类就很容易发送短息,因此都是基于HTTP协议做的一个数据发送而已,接触阿里云的短信服务器后,发现阿里云还增加了非常多的参数,其中包括一些秘钥和签名的内容。短信发送由于比较敏感原因,大多数应用场景是验证码或者一些固定的信息提醒,因此厂商都要求客户按预定的模板来发送,这样限制了短信的应用场景,只能根据业务进行消息定制了。本篇随笔主要介绍阿里云的短信服务的发送处理。

1、短信发送的处理介绍

在短信发送中,阿里云提供自己的SDK封装,以降低使用的难度,不过需要引入它提供的SDK类库;本篇随笔主要介绍基于HTTP方式进行自行的封装处理,这部分代码我从网上摘录并进行一定的调整,测试成功。

使用阿里云的短信服务,需要注册登录自己的阿里云控制台,然后进入AccessKeys的处理界面

技术图片

然后系统会提示需要创建一个新的Key(如果没有的话就创建,否则使用已有的即可)

技术图片

这里我们获取到AccessKey ID 和Access Key Secret两个关键信息,需要用在数据签名的里面的。

另外我们需要创建一个SignName,也就是签名,一般为我们短信提示的公司名称,如【广州爱奇迪】这样的字样。

技术图片

短信是基于模板的,阿里云不能发送随意的内容,因此只能基于模板发送,如验证码或者业务消息,有点类似微信的模板消息了,因此里面可以添加变量发送的。

记得我以前写过一个关于动态变量的信息发送的文章《一个包含动态变量的短信模板设计分析》,就是介绍如何处理变量模板消息的。

阿里云默认提供了一些基础模板,如下所示。

技术图片

一般我们业务可能还需要定制一些业务消息,那么需要审核通过才可以使用新增的模板消息。

短信的发送可以利用API接口进行发送,如下所示是它的API说明

技术图片

如果需要采集用户的回复信息,如一些随访记录,那么需要做一个接口的处理,如下所示。

技术图片 

发送短信的API接口详细说明如下所示。

技术图片

其实请求信息比上面列出的信息多很多,包括秘钥和数据加密信息等的处理,下面详细给出代码说明。 

 

2、模板消息发送

 有了上面的信息介绍,我们大概了解了短信消息发送的处理规则了。

实际上,发送信息的时候,我们可能需要添加很多参数信息,如下代码所示。

            Dictionary<string, string> keyValues = new Dictionary<string, string>();//声明一个字典
            //1.系统参数
            keyValues.Add("SignatureMethod", "HMAC-SHA1");
            keyValues.Add("SignatureNonce", Guid.NewGuid().ToString());
            keyValues.Add("AccessKeyId", AccessKeyId);
            keyValues.Add("SignatureVersion", "1.0");
            keyValues.Add("Timestamp", nowDate);
            keyValues.Add("Format", "Json");//可换成xml

            //2.业务api参数
            keyValues.Add("Action", "SendSms");
            keyValues.Add("Version", "2017-05-25");
            keyValues.Add("RegionId", "cn-hangzhou");
            keyValues.Add("PhoneNumbers", mobile);
            keyValues.Add("SignName", SignName);
            keyValues.Add("TemplateParam", "{"code":"" + code + ""}");
            keyValues.Add("TemplateCode", templateCode);
            keyValues.Add("OutId", "123");

具体我们来贴出不用SDK的短信发送辅助类,如下代码所示。

    /// <summary>
    /// 阿里短信发送
    /// </summary>
    public class SmsHelper
    {
        private const string endpoint = "dysmsapi.aliyuncs.com";
        private const string AccessKeyId = "你的秘钥键";
        private const string AccessKeySecret = "你的秘钥值";
        private const string SignName = "广州爱奇迪";

        /// <summary>
        /// 短信验证码
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string SendSms(string mobile, int code, string templateCode = "SMS_126645400")
        {
            string nowDate = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-dd‘T‘HH:mm:ss‘Z‘");//GTM时间
            Dictionary<string, string> keyValues = new Dictionary<string, string>();//声明一个字典
            //1.系统参数
            keyValues.Add("SignatureMethod", "HMAC-SHA1");
            keyValues.Add("SignatureNonce", Guid.NewGuid().ToString());
            keyValues.Add("AccessKeyId", AccessKeyId);
            keyValues.Add("SignatureVersion", "1.0");
            keyValues.Add("Timestamp", nowDate);
            keyValues.Add("Format", "Json");//可换成xml

            //2.业务api参数
            keyValues.Add("Action", "SendSms");
            keyValues.Add("Version", "2017-05-25");
            keyValues.Add("RegionId", "cn-hangzhou");
            keyValues.Add("PhoneNumbers", mobile);
            keyValues.Add("SignName", SignName);
            keyValues.Add("TemplateParam", "{"code":"" + code + ""}");
            keyValues.Add("TemplateCode", templateCode);
            keyValues.Add("OutId", "123");

            //3.去除签名关键字key
            if (keyValues.ContainsKey("Signature"))
            {
                keyValues.Remove("Signature");
            }

            //4.参数key排序
            Dictionary<string, string> ascDic = keyValues.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value.ToString());
            //5.构造待签名的字符串
            StringBuilder builder = new StringBuilder();
            foreach (var item in ascDic)
            {
                if (item.Key == "SignName")
                {
                }
                else
                {
                    builder.Append("&").Append(specialUrlEncode(item.Key)).Append("=").Append(specialUrlEncode(item.Value));
                }
                if (item.Key == "RegionId")
                {
                    builder.Append("&").Append(specialUrlEncode("SignName")).Append("=").Append(specialUrlEncode(keyValues["SignName"]));
                }
            }
            string sorteQueryString = builder.ToString().Substring(1);

            StringBuilder stringToSign = new StringBuilder();
            stringToSign.Append("GET").Append("&");
            stringToSign.Append(specialUrlEncode("/")).Append("&");
            stringToSign.Append(specialUrlEncode(sorteQueryString));

            string Sign = MySign(AccessKeySecret + "&", stringToSign.ToString());
            //6.签名最后也要做特殊URL编码
            string signture = specialUrlEncode(Sign);

            //最终打印出合法GET请求的URL
            string url = string.Format("http://{0}/?Signature={1}{2}", endpoint, signture, builder);
            string result = GetHtmlFormUrl(url);
            return result;
        }


        /// <summary>
        /// 短信接口C#调用方法
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string GetHtmlFormUrl(string url)
        {
            string strRet = null;
            if (url == null || url.Trim().ToString() == "")
            {
                return strRet;
            }
            string targeturl = url.Trim().ToString();
            try
            {
                HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(targeturl);
                hr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
                hr.Method = "GET";
                hr.Timeout = 30 * 60 * 1000;
                WebResponse hs = hr.GetResponse();
                Stream sr = hs.GetResponseStream();
                StreamReader ser = new StreamReader(sr, Encoding.UTF8);

                strRet = MessageHandle(ser.ReadToEnd());
            }
            catch (Exception ex)
            {
                strRet = "短信发送失败!" + ex.Message;
            }
            return strRet;
        }

        /// <summary>
        /// 验证手机号码是否合法
        /// </summary>
        /// <param name="mobile">电话号码</param>
        /// <returns></returns>
        public static bool IsMobile(string mobile)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(mobile, @"^1[3|4|5|7|8][0-9]d{8}$");
        }

        /// <summary>
        /// URL编码
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string specialUrlEncode(string temp)
        {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < temp.Length; i++)
            {
                string t = temp[i].ToString();
                string k = HttpUtility.UrlEncode(t, Encoding.UTF8);
                if (t == k)
                {
                    stringBuilder.Append(t);
                }
                else
                {
                    stringBuilder.Append(k.ToUpper());
                }
            }
            return stringBuilder.ToString().Replace("+", "%20").Replace("*", "%2A").Replace("%7E", "~");
        }

        /// <summary>
        /// HMACSHA1签名
        /// </summary>
        /// <param name="accessSecret"></param>
        /// <param name="stringToSign"></param>
        /// <returns></returns>
        private static string MySign(string accessSecret, string stringToSign)
        {
            try
            {
                var hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(accessSecret));
                var dataBuffer = Encoding.UTF8.GetBytes(stringToSign);
                var hashBytes = hmacsha1.ComputeHash(dataBuffer);
                string stringbyte = BitConverter.ToString(hashBytes, 0).Replace("-", string.Empty).ToLower();
                byte[] bytes = strToToHexByte(stringbyte);
                return Convert.ToBase64String(bytes);
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }
        /// <summary>
        /// 字符串转16进制字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        /// <summary>
        /// 消息处理机制
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string MessageHandle(string str)
        {
            MessageModel message = JsonConvert.DeserializeObject<MessageModel>(str);
            string result = "";
            switch (message.Code)
            {
                case "OK":
                    result = "短信发送成功!";
                    break;
                case "isp.RAM_PERMISSION_DENY":
                    result = "RAM权限DENY";
                    break;
                case "isv.OUT_OF_SERVICE":
                    result = "业务停机";
                    break;
                case "isv.PRODUCT_UN_SUBSCRIPT":
                    result = "未开通云通信产品的阿里云客户";
                    break;
                case "isv.PRODUCT_UNSUBSCRIBE":
                    result = "产品未开通";
                    break;
                case "isv.ACCOUNT_NOT_EXISTS":
                    result = "账户不存在";
                    break;
                case "isv.ACCOUNT_ABNORMAL":
                    result = "账户异常    ";
                    break;
                case "isv.SMS_TEMPLATE_ILLEGAL":
                    result = "短信模板不合法";
                    break;
                case "isv.SMS_SIGNATURE_ILLEGAL":
                    result = "短信签名不合法";
                    break;
                case "isv.INVALID_PARAMETERS":
                    result = "参数异常";
                    break;
                case "isv.MOBILE_NUMBER_ILLEGAL":
                    result = "非法手机号";
                    break;
                case "isv.MOBILE_COUNT_OVER_LIMIT":
                    result = "手机号码数量超过限制";
                    break;
                case "isv.TEMPLATE_MISSING_PARAMETERS":
                    result = "模板缺少变量";
                    break;
                case "isv.BUSINESS_LIMIT_CONTROL":
                    result = "业务限流";
                    break;
                case "isv.INVALID_JSON_PARAM":
                    result = "JSON参数不合法,只接受字符串值";
                    break;
                case "isv.PARAM_LENGTH_LIMIT":
                    result = "参数超出长度限制";
                    break;
                case "isv.PARAM_NOT_SUPPORT_URL":
                    result = "不支持URL";
                    break;
                case "isv.AMOUNT_NOT_ENOUGH":
                    result = "账户余额不足";
                    break;
                case "isv.TEMPLATE_PARAMS_ILLEGAL":
                    result = "模板变量里包含非法关键字";
                    break;
            }
            return result;
        }

    }

    internal class MessageModel
    {
        public string RequestId { get; set; }
        public string Code { get; set; }
        public string Message { get; set; }
    }

上面代码不是我原创,声明一下,我做了一些修改调整而已,方便辅助类的使用,我们输入我们的企业的秘钥键值,然后发送测试短信即可。

            string tel = "18620292076";
            string result = SmsHelper.SendSms(tel, 123456);
            Console.WriteLine(result);

发送测试,3~5秒就可以收到验证码信息的提示了,如下所示。

技术图片

 以上就是短信消息的发送,希望对使用阿里云短信服务的开发人员有所帮助,辅助类直接就可以使用了。

以上是关于哪位大神,短信接口使用的是阿里云的短信验证平台的主要内容,如果未能解决你的问题,请参考以下文章

使用阿里云的短信服务发送短信

使用阿里云的短信服务发送短信

阿里大鱼短信接口

go 发送短信研究

阿里云短信验证_基于阿里云OpenAPI实现

阿里短信接口 client 是单例吗