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);
}
}