【新增】短信功能增加【单IP每日发送量】限制,增加【IP白名单】【IP黑名单】功能,减少可能存在的恶意请求发送申请。

This commit is contained in:
jianweie code
2023-12-21 21:13:18 +08:00
parent de1b6c8015
commit 9d7bbb5fc0
7 changed files with 202 additions and 64 deletions

View File

@@ -645,6 +645,20 @@ namespace CoreCms.Net.Configuration
/// </summary> /// </summary>
public const string SmsSignature = "smsSignature"; public const string SmsSignature = "smsSignature";
/// <summary>
/// 短信单ip每日发送量
/// </summary>
public const string SmsIpSendNumber = "smsIpSendNumber";
/// <summary>
/// 短信发送IP白名单
/// </summary>
public const string SmsIpSendWhiteList= "smsIpSendWhiteList";
/// <summary>
/// 短信发送IP黑名单
/// </summary>
public const string SmsIpSendBlackList = "smsIpSendBlackList";
/// <summary> /// <summary>
/// 账户注册-短信内容模板 /// 账户注册-短信内容模板

View File

@@ -214,6 +214,9 @@ namespace CoreCms.Net.Configuration
di.Add(SystemSettingConstVars.SmsPassword, new DictionaryKeyValues() { sKey = "密码", sValue = "" }); di.Add(SystemSettingConstVars.SmsPassword, new DictionaryKeyValues() { sKey = "密码", sValue = "" });
di.Add(SystemSettingConstVars.SmsApiUrl, new DictionaryKeyValues() { sKey = "Api地址", sValue = "http://sms.corecms.net:9999/sms.aspx" }); di.Add(SystemSettingConstVars.SmsApiUrl, new DictionaryKeyValues() { sKey = "Api地址", sValue = "http://sms.corecms.net:9999/sms.aspx" });
di.Add(SystemSettingConstVars.SmsSignature, new DictionaryKeyValues() { sKey = "短信签名", sValue = "" }); di.Add(SystemSettingConstVars.SmsSignature, new DictionaryKeyValues() { sKey = "短信签名", sValue = "" });
di.Add(SystemSettingConstVars.SmsIpSendNumber, new DictionaryKeyValues() { sKey = "单Ip每日发送量", sValue = "20" });
di.Add(SystemSettingConstVars.SmsIpSendWhiteList, new DictionaryKeyValues() { sKey = "发送IP白名单", sValue = "127.0.0.1|192.168.1.1|192.168.0.1" });
di.Add(SystemSettingConstVars.SmsIpSendBlackList, new DictionaryKeyValues() { sKey = "发送IP黑名单", sValue = "8.8.8.8|2.2.2.2" });
//附件存储 //附件存储
di.Add(SystemSettingConstVars.FilesStorageType, new DictionaryKeyValues() { sKey = "存储方式", sValue = "LocalStorage" }); di.Add(SystemSettingConstVars.FilesStorageType, new DictionaryKeyValues() { sKey = "存储方式", sValue = "LocalStorage" });

View File

@@ -12467,6 +12467,21 @@
短信签名 短信签名
</summary> </summary>
</member> </member>
<member name="P:CoreCms.Net.Model.ViewModels.Sms.SmsOptions.SmsIpSendNumber">
<summary>
短信单ip每日发送量
</summary>
</member>
<member name="P:CoreCms.Net.Model.ViewModels.Sms.SmsOptions.SmsIpSendWhiteList">
<summary>
短信发送IP白名单
</summary>
</member>
<member name="P:CoreCms.Net.Model.ViewModels.Sms.SmsOptions.SmsIpSendBlackList">
<summary>
短信发送IP黑名单
</summary>
</member>
<member name="T:CoreCms.Net.Model.ViewModels.Sms.SMSReturnData"> <member name="T:CoreCms.Net.Model.ViewModels.Sms.SMSReturnData">
<summary> <summary>
短信发送回调结果 短信发送回调结果

View File

@@ -45,6 +45,24 @@ namespace CoreCms.Net.Model.ViewModels.Sms
/// 短信签名 /// 短信签名
/// </summary> /// </summary>
public string Signature { get; set; } public string Signature { get; set; }
/// <summary>
/// 短信单ip每日发送量
/// </summary>
public int SmsIpSendNumber { get; set; } = 20;
/// <summary>
/// 短信发送IP白名单
/// </summary>
public string SmsIpSendWhiteList { get; set; }
/// <summary>
/// 短信发送IP黑名单
/// </summary>
public string SmsIpSendBlackList { get; set; }
} }
/// <summary> /// <summary>

View File

@@ -9,6 +9,8 @@
***********************************************************************/ ***********************************************************************/
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using CoreCms.Net.Configuration; using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository; using CoreCms.Net.IRepository;
@@ -78,8 +80,37 @@ namespace CoreCms.Net.Services
Random rd = new Random(); Random rd = new Random();
int codeNumber = rd.Next(100000, 999999); int codeNumber = rd.Next(100000, 999999);
//获取是否存在
var dt = DateTime.Now; var dt = DateTime.Now;
//获取当前ip今日的发送记录
var ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1";
if (string.IsNullOrEmpty(ip))
{
jm.msg = "短信发送IP获取失败";
return jm;
}
var black = smsOptions.SmsIpSendBlackList.Split('|').ToList();
if (black.Count > 0 && black.Contains(ip))
{
jm.msg = "此IP被禁止短信业务";
return jm;
}
var white = smsOptions.SmsIpSendWhiteList.Split('|').ToList();
if (white.Count <= 0 || !white.Contains(ip))
{
var startDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, DateTimeKind.Utc);
var endDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59, DateTimeKind.Utc);
var sendCount = await _dal.GetCountAsync(p => p.ip.Equals(ip) && p.createTime > startDateTime && p.createTime < endDateTime);
if (smsOptions.SmsIpSendNumber > 0 && sendCount > smsOptions.SmsIpSendNumber)
{
jm.msg = "此IP被已超过每日短信发送限额。";
return jm;
}
}
//获取是否存在
var endDt = dt.AddMinutes(10); var endDt = dt.AddMinutes(10);
var oldLog = await _dal.QueryByClauseAsync(p => p.code == type && p.mobile == mobile && p.createTime > dt && p.createTime < endDt, p => p.id, OrderByType.Desc); var oldLog = await _dal.QueryByClauseAsync(p => p.code == type && p.mobile == mobile && p.createTime > dt && p.createTime < endDt, p => p.id, OrderByType.Desc);
@@ -87,9 +118,9 @@ namespace CoreCms.Net.Services
{ {
oldLog = new CoreCmsSms(); oldLog = new CoreCmsSms();
oldLog.code = type; oldLog.code = type;
oldLog.createTime = DateTime.Now; oldLog.createTime = dt;
oldLog.mobile = mobile; oldLog.mobile = mobile;
oldLog.ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1"; oldLog.ip = ip;
oldLog.isUsed = false; oldLog.isUsed = false;
var obj = new var obj = new
{ {
@@ -206,6 +237,36 @@ namespace CoreCms.Net.Services
jm.msg = "短信功能未开启"; jm.msg = "短信功能未开启";
return jm; return jm;
} }
var dt = DateTime.Now;
//获取当前ip今日的发送记录
var ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "";
if (string.IsNullOrEmpty(ip))
{
jm.msg = "短信发送IP获取失败";
return jm;
}
var black = smsOptions.SmsIpSendBlackList.Split('|').ToList();
if (black.Count > 0 && black.Contains(ip))
{
jm.msg = "此IP被禁止短信业务";
return jm;
}
var white = smsOptions.SmsIpSendWhiteList.Split('|').ToList();
if (white.Count <= 0 || !white.Contains(ip))
{
var startDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0,
DateTimeKind.Utc);
var endDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59,
DateTimeKind.Utc);
var sendCount = await _dal.GetCountAsync(p => p.ip.Equals(ip) && p.createTime > startDateTime && p.createTime < endDateTime);
if (smsOptions.SmsIpSendNumber > 0 && sendCount > smsOptions.SmsIpSendNumber)
{
jm.msg = "此IP被已超过每日短信发送限额。";
return jm;
}
}
if (string.IsNullOrEmpty(mobile)) if (string.IsNullOrEmpty(mobile))
{ {
@@ -215,7 +276,6 @@ namespace CoreCms.Net.Services
var isUsed = false; var isUsed = false;
if (code == GlobalEnumVars.SmsMessageTypes.Reg.ToString() || code == GlobalEnumVars.SmsMessageTypes.Login.ToString() || code == GlobalEnumVars.SmsMessageTypes.Veri.ToString()) if (code == GlobalEnumVars.SmsMessageTypes.Reg.ToString() || code == GlobalEnumVars.SmsMessageTypes.Login.ToString() || code == GlobalEnumVars.SmsMessageTypes.Veri.ToString())
{ {
var dt = DateTime.Now;
var newCreateTime = DateTime.Now.AddSeconds(-60); var newCreateTime = DateTime.Now.AddSeconds(-60);
var smsInfo = await _dal.QueryByClauseAsync(p => var smsInfo = await _dal.QueryByClauseAsync(p =>
p.mobile == mobile && p.code == code && p.createTime < newCreateTime && p.isUsed == false); p.mobile == mobile && p.code == code && p.createTime < newCreateTime && p.isUsed == false);
@@ -227,7 +287,7 @@ namespace CoreCms.Net.Services
jm.msg = "两次发送时间间隔小于60秒"; jm.msg = "两次发送时间间隔小于60秒";
return jm; return jm;
} }
parameters = JObject.Parse(smsInfo.parameters); ; parameters = JObject.Parse(smsInfo.parameters);
} }
else else
{ {
@@ -360,8 +420,8 @@ namespace CoreCms.Net.Services
oldLog.code = code; oldLog.code = code;
oldLog.parameters = JsonConvert.SerializeObject(parameters); oldLog.parameters = JsonConvert.SerializeObject(parameters);
oldLog.contentBody = str; oldLog.contentBody = str;
oldLog.createTime = DateTime.Now; oldLog.createTime = dt;
oldLog.ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1"; oldLog.ip = ip;
oldLog.isUsed = isUsed; oldLog.isUsed = isUsed;
await _dal.InsertAsync(oldLog); await _dal.InsertAsync(oldLog);

View File

@@ -220,6 +220,9 @@ namespace CoreCms.Net.Services
sms.Password = GetValue(SystemSettingConstVars.SmsPassword, configs, settings); sms.Password = GetValue(SystemSettingConstVars.SmsPassword, configs, settings);
sms.Signature = GetValue(SystemSettingConstVars.SmsSignature, configs, settings); sms.Signature = GetValue(SystemSettingConstVars.SmsSignature, configs, settings);
sms.ApiUrl = GetValue(SystemSettingConstVars.SmsApiUrl, configs, settings); sms.ApiUrl = GetValue(SystemSettingConstVars.SmsApiUrl, configs, settings);
sms.SmsIpSendNumber= GetValue(SystemSettingConstVars.SmsIpSendNumber, configs, settings).ObjectToInt(20);
sms.SmsIpSendWhiteList = GetValue(SystemSettingConstVars.SmsIpSendWhiteList, configs, settings);
sms.SmsIpSendBlackList = GetValue(SystemSettingConstVars.SmsIpSendBlackList, configs, settings);
return sms; return sms;
} }

View File

@@ -19,69 +19,94 @@
.layui-tab-content { padding: 15px 0; } .layui-tab-content { padding: 15px 0; }
</style> </style>
<script type="text/html" template lay-type="Post" lay-url="{{ layui.setter.apiUrl }}Api/CoreCmsSmsSetting/GetIndex" lay-done="layui.data.done(d);"> <script type="text/html" template lay-type="Post" lay-url="{{ layui.setter.apiUrl }}Api/CoreCmsSmsSetting/GetIndex" lay-done="layui.data.done(d);">
<div class="layui-fluid"> <div class="layui-fluid">
<div class="layui-row layui-col-space15"> <div class="layui-row layui-col-space15">
<div class="layui-col-md12"> <div class="layui-col-md12">
<div class="layui-card"> <div class="layui-card">
<div class="layui-card-body"> <div class="layui-card-body">
<div class="layui-tab layui-tab-card" lay-filter="setting"> <div class="layui-tab layui-tab-card" lay-filter="setting">
<ul class="layui-tab-title"> <ul class="layui-tab-title">
<li lay-id="sms" class="layui-this">短信设置</li> <li lay-id="sms" class="layui-this">短信设置</li>
<li lay-id="smsstr">短信内容模板</li> <li lay-id="smsstr">短信内容模板</li>
</ul> </ul>
<div class="layui-tab-content"> <div class="layui-tab-content">
<div class="layui-tab-item layui-show"> <div class="layui-tab-item layui-show">
<div class="layui-form coreshop-form"> <div class="layui-form coreshop-form">
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsEnabled']['sKey']}}</label> <label class="layui-form-label">{{d.data.configs['smsEnabled']['sKey']}}</label>
<div class="layui-input-inline layui-inline-7"> <div class="layui-input-inline layui-inline-7">
<input type="radio" name="smsEnabled" value="1" title="开启" {{d.data.configs['smsEnabled']['sValue']==="1" ? 'checked':''}}> <input type="radio" name="smsEnabled" value="1" title="开启" {{d.data.configs['smsEnabled']['sValue']==="1" ? 'checked':''}}>
<input type="radio" name="smsEnabled" value="2" title="关闭" {{d.data.configs['smsEnabled']['sValue']==="2" ? 'checked':''}}> <input type="radio" name="smsEnabled" value="2" title="关闭" {{d.data.configs['smsEnabled']['sValue']==="2" ? 'checked':''}}>
</div> </div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsUserId']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsUserId" value="{{d.data.configs['smsUserId']['sValue']}}" lay-verify="number" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsAccount']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsAccount" value="{{d.data.configs['smsAccount']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsPassword']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsPassword" value="{{d.data.configs['smsPassword']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsApiUrl']['sKey']}}</label>
<div class="layui-input-inline layui-inline-12">
<input type="text" name="smsApiUrl" value="{{d.data.configs['smsApiUrl']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">默认地址为http://sms.corecms.net:9999/sms.aspx</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsSignature']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsSignature" value="{{d.data.configs['smsSignature']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">短信签名2-8个汉字以内</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsIpSendNumber']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsIpSendNumber" value="{{d.data.configs['smsIpSendNumber']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">单个ip每日请求的相关业务发送短信的数量比如用户注册登录等</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsIpSendWhiteList']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<textarea name="smsIpSendWhiteList" cols="30" rows="10" class="layui-input" style="height: 100px; padding: 10px">{{d.data.configs['smsIpSendWhiteList']['sValue']}}</textarea>
</div>
<div class="layui-form-mid layui-word-aux">设置的ip将不受到每日发送的限制一般是设置站点的ip地址使用小写分割线|隔开</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsIpSendBlackList']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<textarea name="smsIpSendBlackList" cols="30" rows="10" class="layui-input" style="height: 100px; padding: 10px">{{d.data.configs['smsIpSendBlackList']['sValue']}}</textarea>
</div>
<div class="layui-form-mid layui-word-aux">设置的ip地址将无法发送短信请求业务使用小写分割线|隔开</div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsUserId']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsUserId" value="{{d.data.configs['smsUserId']['sValue']}}" lay-verify="number" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsAccount']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsAccount" value="{{d.data.configs['smsAccount']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsPassword']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsPassword" value="{{d.data.configs['smsPassword']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsApiUrl']['sKey']}}</label>
<div class="layui-input-inline layui-inline-12">
<input type="text" name="smsApiUrl" value="{{d.data.configs['smsApiUrl']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">默认地址为http://sms.corecms.net:9999/sms.aspx</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{d.data.configs['smsSignature']['sKey']}}</label>
<div class="layui-input-inline layui-inline-5">
<input type="text" name="smsSignature" value="{{d.data.configs['smsSignature']['sValue']}}" lay-verify="title" autocomplete="off" placeholder="" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">短信签名2-8个汉字以内</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">&nbsp;</label> <label class="layui-form-label">&nbsp;</label>
<div class="layui-input-block"> <div class="layui-input-block">