.net core 华为云发送短信
Service
/// <summary> /// 发送验证码 /// </summary> /// <param name="phone">手机号码</param> /// <returns></returns> public async Task<Result> SendPhoneVerifCode(string phone) { try { var options = new ShortMessageOptions(); _configuration.GetSection(ShortMessageOptions.ShortMessage).Bind(options); var verifCode = PhoneVerifCodeHelper.SendPhoneVerifCode(phone, options); var model = new PhoneVerifCode { CreatedBy = 0, CreatedTime = DateTime.UtcNow, Phone = phone, VerifCode = verifCode, EffectiveTime = DateTime.UtcNow.AddMinutes(+5), }; await _phoneVerifCodeRepository.InsertAsync(model); return Result.Success(); } catch (Exception) { return Result.Fail(ResultCodeConsts.Exception, "发送验证码错误!"); } }
实体
public class ShortMessageOptions { public const string ShortMessage = "ShortMessage"; /// <summary> /// 接口地址 /// </summary> public string ApiAddress { get; set; } /// <summary> /// AppKey /// </summary> public string AppKey { get; set; } /// <summary> /// AppSecret /// </summary> public string AppSecret { get; set; } /// <summary> /// 通道号 /// </summary> public string Sender { get; set; } /// <summary> /// 模板Id /// </summary> public string TemplateId { get; set; } /// <summary> /// 签名名称 /// </summary> public string Signature { get; set; } }
配置:ShortMessage
SendPhoneVerifCode方法
public class PhoneVerifCodeHelper { public static string SendPhoneVerifCode(string phone, ShortMessageOptions options) { string apiAddress = options.ApiAddress; // APP接入地址 string appKey = options.AppKey; // APPKey string appSecret = options.AppSecret; // APPSecret string sender = options.Sender; // 通道号 string templateId = options.TemplateId; // 模板ID string signature = options.Signature; // 签名 string[] receiver = { phone }; // 接收号码 // 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 string statusCallBack = ""; /* * 选填,使用无变量模板时请赋空值 string[] templateParas = {}; */ var ran = new Random().Next(100000, 999999); string[] templateParas = { ran.ToString() }; // 模板变量 ArrayList smsContent = new ArrayList { // smsContent,不携带签名名称时,signature请填null InitDiffSms(receiver, templateId, templateParas, signature), }; try { // 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题 HttpClient client = new HttpClient(); ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; // 请求Headers client.DefaultRequestHeaders.Add("Authorization", "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\""); client.DefaultRequestHeaders.Add("X-WSSE", BuildWSSEHeader(appKey, appSecret)); // 请求Body var body = new Dictionary<string, object>{ {"from", sender}, {"statusCallback", statusCallBack}, {"smsContent", smsContent} }; HttpContent content = new StringContent(JsonConvert.SerializeObject(body)); // 请求Headers中的Content-Type参数 content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var response = client.PostAsync(apiAddress, content).Result; var res = response.Content.ReadAsStringAsync().Result; return ran.ToString(); } catch (Exception e) { return e.Message.ToString(); } } /// <summary> /// 构造smsContent参数值 /// </summary> /// <param name="receiver"></param> /// <param name="templateId"></param> /// <param name="templateParas"></param> /// <param name="signature">签名名称,使用国内短信通用模板时填写</param> /// <returns></returns> static Dictionary<string, object> InitDiffSms(string[] receiver, string templateId, string[] templateParas, string signature) { Dictionary<string, object> dic = new Dictionary<string, object> { {"to", receiver}, {"templateId", templateId}, {"templateParas", templateParas} }; if (!signature.Equals(null) && signature.Length > 0) { dic.Add("signature", signature); } return dic; } /// <summary> /// 构造X-WSSE参数值 /// </summary> /// <param name="appKey"></param> /// <param name="appSecret"></param> /// <returns></returns> static string BuildWSSEHeader(string appKey, string appSecret) { string now = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"); // Created string nonce = Guid.NewGuid().ToString().Replace("-", ""); // Nonce byte[] material = Encoding.UTF8.GetBytes(nonce + now + appSecret); byte[] hashed = SHA256Managed.Create().ComputeHash(material); string hexdigest = BitConverter.ToString(hashed).Replace("-", ""); string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(hexdigest)); // PasswordDigest return String.Format("UsernameToken Username=\"{0}\",PasswordDigest=\"{1}\",Nonce=\"{2}\",Created=\"{3}\"", appKey, base64, nonce, now); } }