feat: 增加腾云云短信接口
This commit is contained in:
parent
908dd4cc0e
commit
84d7d43058
|
@ -3,6 +3,7 @@ using Bootstrap.DataAccess;
|
||||||
using Bootstrap.Security.Mvc;
|
using Bootstrap.Security.Mvc;
|
||||||
using Longbow.GiteeAuth;
|
using Longbow.GiteeAuth;
|
||||||
using Longbow.GitHubAuth;
|
using Longbow.GitHubAuth;
|
||||||
|
using Longbow.Web.SMS;
|
||||||
using Longbow.WeChatAuth;
|
using Longbow.WeChatAuth;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
@ -11,7 +12,6 @@ using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -109,12 +109,12 @@ namespace Bootstrap.Admin.Controllers
|
||||||
Password = code,
|
Password = code,
|
||||||
Icon = "default.jpg",
|
Icon = "default.jpg",
|
||||||
Description = "手机用户",
|
Description = "手机用户",
|
||||||
App = provider.Option.App
|
App = provider.Options.App
|
||||||
};
|
};
|
||||||
UserHelper.Save(user);
|
UserHelper.Save(user);
|
||||||
|
|
||||||
// 根据配置文件设置默认角色
|
// 根据配置文件设置默认角色
|
||||||
var roles = RoleHelper.Retrieves().Where(r => provider.Option.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id);
|
var roles = RoleHelper.Retrieves().Where(r => provider.Options.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id);
|
||||||
RoleHelper.SaveByUserId(user.Id, roles);
|
RoleHelper.SaveByUserId(user.Id, roles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
using Bootstrap.DataAccess;
|
using Bootstrap.DataAccess;
|
||||||
using Bootstrap.Security.Authentication;
|
using Bootstrap.Security.Authentication;
|
||||||
using Longbow.Web.Mvc;
|
using Longbow.Web.Mvc;
|
||||||
|
using Longbow.Web.SMS;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Bootstrap.Admin.Controllers.Api
|
namespace Bootstrap.Admin.Controllers.Api
|
||||||
|
@ -52,7 +52,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
||||||
/// <param name="phone"></param>
|
/// <param name="phone"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
public async Task<bool> Put([FromServices]ISMSProvider provider, [FromQuery]string phone) => string.IsNullOrEmpty(phone) ? false : await provider.SendCodeAsync(phone);
|
public async Task<SMSResult> Put([FromServices]ISMSProvider provider, [FromQuery]string phone) => string.IsNullOrEmpty(phone) ? new SMSResult() { Result = false, Msg = "手机号不可为空" } : await provider.SendCodeAsync(phone);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 跨域握手协议
|
/// 跨域握手协议
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Longbow.Web.SMS;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Longbow.Web.SMS.Tencent;
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
|
@ -25,228 +15,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IServiceCollection AddSMSProvider(this IServiceCollection services)
|
public static IServiceCollection AddSMSProvider(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddTransient<ISMSProvider, DefaultSMSProvider>();
|
services.AddTransient<ISMSProvider, TencentSMSProvider>();
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 短信登录接口
|
|
||||||
/// </summary>
|
|
||||||
public interface ISMSProvider
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 手机下发验证码方法
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="phoneNumber">手机号</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<bool> SendCodeAsync(string phoneNumber);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 验证手机验证码是否正确方法
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="phoneNumber">手机号</param>
|
|
||||||
/// <param name="code">验证码</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
bool Validate(string phoneNumber, string code);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得 配置信息
|
|
||||||
/// </summary>
|
|
||||||
SMSOptions Option { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 手机号登陆帮助类
|
|
||||||
/// </summary>
|
|
||||||
internal class DefaultSMSProvider : ISMSProvider
|
|
||||||
{
|
|
||||||
private static ConcurrentDictionary<string, AutoExpireValidateCode> _pool = new ConcurrentDictionary<string, AutoExpireValidateCode>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得 短信配置信息
|
|
||||||
/// </summary>
|
|
||||||
public SMSOptions Option { get; protected set; }
|
|
||||||
|
|
||||||
private HttpClient _client;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造函数
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="configuration"></param>
|
|
||||||
/// <param name="factory"></param>
|
|
||||||
public DefaultSMSProvider(IConfiguration configuration, IHttpClientFactory factory)
|
|
||||||
{
|
|
||||||
Option = configuration.GetSection<SMSOptions>().Get<SMSOptions>();
|
|
||||||
_client = factory.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 下发验证码方法
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="phoneNumber"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<bool> SendCodeAsync(string phoneNumber)
|
|
||||||
{
|
|
||||||
Option.Timestamp = (DateTimeOffset.UtcNow.Ticks - 621355968000000000) / 10000000;
|
|
||||||
Option.Phone = phoneNumber;
|
|
||||||
var requestParameters = new Dictionary<string, string>()
|
|
||||||
{
|
|
||||||
{ "CompanyCode", Option.CompanyCode },
|
|
||||||
{ "Phone", Option.Phone },
|
|
||||||
{ "TimeStamp", Option.Timestamp.ToString() },
|
|
||||||
{ "Sign", Sign() }
|
|
||||||
};
|
|
||||||
|
|
||||||
var url = QueryHelpers.AddQueryString(Option.RequestUrl, requestParameters);
|
|
||||||
var req = await _client.GetAsync(url);
|
|
||||||
var content = await req.Content.ReadAsStringAsync();
|
|
||||||
var result = JsonSerializer.Deserialize<SMSResult>(content, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
|
|
||||||
var ret = false;
|
|
||||||
if (result.Code == 1)
|
|
||||||
{
|
|
||||||
_pool.AddOrUpdate(Option.Phone, key => new AutoExpireValidateCode(Option.Phone, result.Data, Option.Expires), (key, v) => v.Reset(result.Data));
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new Exception(result.Msg).Log(new NameValueCollection()
|
|
||||||
{
|
|
||||||
["UserId"] = Option.Phone,
|
|
||||||
["url"] = url,
|
|
||||||
["content"] = content
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 验证验证码方法
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="phone">手机号</param>
|
|
||||||
/// <param name="code">验证码</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Validate(string phone, string code) => _pool.TryGetValue(phone, out var signKey) && Hash($"{code}{Option.MD5Key}") == signKey.Code;
|
|
||||||
|
|
||||||
private string Sign()
|
|
||||||
{
|
|
||||||
return Hash($"{Option.CompanyCode}{Option.Phone}{Option.Timestamp}{Option.MD5Key}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string Hash(string data)
|
|
||||||
{
|
|
||||||
using (var md5 = MD5.Create())
|
|
||||||
{
|
|
||||||
var sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(data)));
|
|
||||||
sign = sign.Replace("-", "").ToLowerInvariant();
|
|
||||||
return sign;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SMSResult
|
|
||||||
{
|
|
||||||
public int Code { get; set; }
|
|
||||||
|
|
||||||
public string Data { get; set; }
|
|
||||||
|
|
||||||
public string Msg { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AutoExpireValidateCode
|
|
||||||
{
|
|
||||||
public AutoExpireValidateCode(string phone, string code, TimeSpan expires)
|
|
||||||
{
|
|
||||||
Phone = phone;
|
|
||||||
Code = code;
|
|
||||||
Expires = expires;
|
|
||||||
RunAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Code { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Phone { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan Expires { get; set; }
|
|
||||||
|
|
||||||
private CancellationTokenSource _tokenSource;
|
|
||||||
|
|
||||||
private Task RunAsync() => Task.Run(() =>
|
|
||||||
{
|
|
||||||
_tokenSource = new CancellationTokenSource();
|
|
||||||
if (!_tokenSource.Token.WaitHandle.WaitOne(Expires)) _pool.TryRemove(Phone, out var _);
|
|
||||||
});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="code"></param>
|
|
||||||
public AutoExpireValidateCode Reset(string code)
|
|
||||||
{
|
|
||||||
Code = code;
|
|
||||||
_tokenSource.Cancel();
|
|
||||||
RunAsync();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 短信网关配置类
|
|
||||||
/// </summary>
|
|
||||||
public class SMSOptions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 公司编码
|
|
||||||
/// </summary>
|
|
||||||
public string CompanyCode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 下发手机号码
|
|
||||||
/// </summary>
|
|
||||||
public string Phone { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 签名密钥
|
|
||||||
/// </summary>
|
|
||||||
public string MD5Key { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 时间戳
|
|
||||||
/// </summary>
|
|
||||||
public long Timestamp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 验证码有效时长
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan Expires { get; set; } = TimeSpan.FromMinutes(5);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 角色集合
|
|
||||||
/// </summary>
|
|
||||||
public ICollection<string> Roles { get; } = new HashSet<string>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 登陆后首页
|
|
||||||
/// </summary>
|
|
||||||
public string HomePath { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 默认授权 App
|
|
||||||
/// </summary>
|
|
||||||
public string App { get; set; } = "0";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得/设置 短信下发网关地址
|
|
||||||
/// </summary>
|
|
||||||
public string RequestUrl { get; set; } = "http://open.bluegoon.com/api/sms/sendcode";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,13 +70,8 @@
|
||||||
"ClientSecret": "3427f2d901ba9afc76c1842a7303b2d67f8e098e71acc15051f89fe6f3d265db",
|
"ClientSecret": "3427f2d901ba9afc76c1842a7303b2d67f8e098e71acc15051f89fe6f3d265db",
|
||||||
"CallbackPath": "/signin-gitee",
|
"CallbackPath": "/signin-gitee",
|
||||||
"HomePath": "/Admin/Profiles",
|
"HomePath": "/Admin/Profiles",
|
||||||
"Scope": [
|
"Scope": [ "user_info", "projects" ],
|
||||||
"user_info",
|
"Roles": [ "Administrators" ],
|
||||||
"projects"
|
|
||||||
],
|
|
||||||
"Roles": [
|
|
||||||
"Administrators"
|
|
||||||
],
|
|
||||||
"App": "0",
|
"App": "0",
|
||||||
"StarredUrl": "https://gitee.com/api/v5/user/starred/LongbowEnterprise/BootstrapAdmin"
|
"StarredUrl": "https://gitee.com/api/v5/user/starred/LongbowEnterprise/BootstrapAdmin"
|
||||||
},
|
},
|
||||||
|
@ -86,13 +81,8 @@
|
||||||
"ClientSecret": "ffa759ca599df941b869efecb5e750bc1b27334e",
|
"ClientSecret": "ffa759ca599df941b869efecb5e750bc1b27334e",
|
||||||
"CallbackPath": "/signin-github",
|
"CallbackPath": "/signin-github",
|
||||||
"HomePath": "/Admin/Profiles",
|
"HomePath": "/Admin/Profiles",
|
||||||
"Scope": [
|
"Scope": [ "user_info", "repo" ],
|
||||||
"user_info",
|
"Roles": [ "Administrators" ],
|
||||||
"repo"
|
|
||||||
],
|
|
||||||
"Roles": [
|
|
||||||
"Administrators"
|
|
||||||
],
|
|
||||||
"App": "0",
|
"App": "0",
|
||||||
"StarredUrl": "https://api.github.com/user/starred/ArgoZhang/BootstrapAdmin"
|
"StarredUrl": "https://api.github.com/user/starred/ArgoZhang/BootstrapAdmin"
|
||||||
},
|
},
|
||||||
|
@ -102,23 +92,27 @@
|
||||||
"ClientSecret": "<secret>",
|
"ClientSecret": "<secret>",
|
||||||
"CallbackPath": "/signin-weixin",
|
"CallbackPath": "/signin-weixin",
|
||||||
"HomePath": "/Admin/Profiles",
|
"HomePath": "/Admin/Profiles",
|
||||||
"Scope": [
|
"Scope": [ "snsapi_login" ],
|
||||||
"snsapi_login"
|
"Roles": [ "Administrators" ],
|
||||||
],
|
|
||||||
"Roles": [
|
|
||||||
"Administrators"
|
|
||||||
],
|
|
||||||
"App": "0"
|
"App": "0"
|
||||||
},
|
},
|
||||||
"SMSOptions": {
|
"SMSOptions": {
|
||||||
"CompanyCode": "<CompanyCode>",
|
"CompanyCode": "<CompanyCode>",
|
||||||
"MD5Key": "MD5Key",
|
"MD5Key": "MD5Key",
|
||||||
"Roles": [
|
"Roles": [ "Administrators" ],
|
||||||
"Administrators"
|
|
||||||
],
|
|
||||||
"HomePath": "/Admin/Profiles",
|
"HomePath": "/Admin/Profiles",
|
||||||
"App": "0"
|
"App": "0"
|
||||||
},
|
},
|
||||||
|
"TencentSMSOptions": {
|
||||||
|
"AppId": "<TencentAppId>",
|
||||||
|
"AppKey": "<TencentAppKey>",
|
||||||
|
"TplId": 0,
|
||||||
|
"Sign": "<TencentSign>",
|
||||||
|
"Roles": [ "Default" ],
|
||||||
|
"HomePath": "/Admin/Profiles",
|
||||||
|
"App": "Demo",
|
||||||
|
"Debug": true
|
||||||
|
},
|
||||||
"AppMenus": [
|
"AppMenus": [
|
||||||
"首页",
|
"首页",
|
||||||
"测试页面",
|
"测试页面",
|
||||||
|
|
|
@ -105,6 +105,15 @@
|
||||||
"HomePath": "/Home/Index",
|
"HomePath": "/Home/Index",
|
||||||
"App": "2"
|
"App": "2"
|
||||||
},
|
},
|
||||||
|
"TencentSMSOptions": {
|
||||||
|
"AppId": "<TencentAppId>",
|
||||||
|
"AppKey": "<TencentAppKey>",
|
||||||
|
"TplId": 0,
|
||||||
|
"Sign": "<TencentSign>",
|
||||||
|
"Roles": [ "Default" ],
|
||||||
|
"HomePath": "/Admin/Profiles",
|
||||||
|
"App": "Demo"
|
||||||
|
},
|
||||||
"LongbowCache": {
|
"LongbowCache": {
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"CorsItems": [
|
"CorsItems": [
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('button[type="submit"]').on('click', function (e) {
|
var $loginButton = $('button[type="submit"]').on('click', function (e) {
|
||||||
$.captchaCheck($('#login .slidercaptcha'), function () {
|
$.captchaCheck($('#login .slidercaptcha'), function () {
|
||||||
$('form').submit();
|
$('form').submit();
|
||||||
});
|
});
|
||||||
|
@ -165,6 +165,7 @@
|
||||||
$loginMobile.removeClass('d-none');
|
$loginMobile.removeClass('d-none');
|
||||||
|
|
||||||
$this.attr('data-value', 'sms').text('用户名密码登陆');
|
$this.attr('data-value', 'sms').text('用户名密码登陆');
|
||||||
|
$loginButton.attr('data-original-title', '请输入手机号码并点击发送验证码');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// sms model
|
// sms model
|
||||||
|
@ -174,6 +175,7 @@
|
||||||
$loginMobile.addClass('d-none');
|
$loginMobile.addClass('d-none');
|
||||||
|
|
||||||
$this.attr('data-value', 'username').text('短信验证登陆');
|
$this.attr('data-value', 'username').text('短信验证登陆');
|
||||||
|
$loginButton.attr('data-original-title', '不填写密码默认使用 Gitee 认证');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -195,16 +197,22 @@
|
||||||
url: apiUrl,
|
url: apiUrl,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
callback: function (result) {
|
callback: function (result) {
|
||||||
$this.attr('data-original-title', result ? "发送成功" : "短信登录体验活动结束").tooltip('show');
|
$this.attr('data-original-title', result.Result ? "发送成功" : "短信登录体验活动结束").tooltip('show');
|
||||||
var handler = setTimeout(function () {
|
var handler = setTimeout(function () {
|
||||||
clearTimeout(handler);
|
clearTimeout(handler);
|
||||||
$this.tooltip('hide').attr('data-original-title', "点击发送验证码");
|
$this.tooltip('hide').attr('data-original-title', "点击发送验证码");
|
||||||
}, 1000);
|
}, 2000);
|
||||||
|
|
||||||
if (result) {
|
if (result.Result) {
|
||||||
// send success
|
// send success
|
||||||
$this.text('已发送').attr('disabled', true);
|
$this.text('已发送').attr('disabled', true);
|
||||||
$('#code').removeAttr('disabled');
|
$('#code').removeAttr('disabled');
|
||||||
|
if (result.Data === null) $loginButton.attr('data-original-title', '请输入验证码');
|
||||||
|
else {
|
||||||
|
$('#code').val(result.Data);
|
||||||
|
$loginButton.attr('data-original-title', '点击登录系统');
|
||||||
|
}
|
||||||
|
|
||||||
timeHanlder = setTimeout(function () {
|
timeHanlder = setTimeout(function () {
|
||||||
clearTimeout(timeHanlder);
|
clearTimeout(timeHanlder);
|
||||||
var count = 299;
|
var count = 299;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
|
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
|
||||||
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
||||||
<PackageReference Include="Longbow.Tasks" Version="3.0.0" />
|
<PackageReference Include="Longbow.Tasks" Version="3.0.0" />
|
||||||
<PackageReference Include="Longbow.Web" Version="3.0.0" />
|
<PackageReference Include="Longbow.Web" Version="3.0.1-beta1" />
|
||||||
<PackageReference Include="Longbow.WeChatAuth" Version="3.0.0" />
|
<PackageReference Include="Longbow.WeChatAuth" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="3.0.0" />
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="3.0.0" />
|
||||||
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
|
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
using Longbow.Data;
|
using Longbow.Data;
|
||||||
|
using Longbow.Web.SMS;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc.Testing;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
using Microsoft.AspNetCore.Mvc.Testing.Handlers;
|
using Microsoft.AspNetCore.Mvc.Testing.Handlers;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using UnitTest;
|
using UnitTest;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Bootstrap.Admin
|
namespace Bootstrap.Admin
|
||||||
{
|
{
|
||||||
|
@ -138,14 +139,14 @@ namespace Bootstrap.Admin
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获得 短信配置信息
|
/// 获得 短信配置信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SMSOptions Option { get; protected set; } = new SMSOptions();
|
public SMSOptions Options { get; protected set; } = new SMSOptions();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下发验证码方法
|
/// 下发验证码方法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="phoneNumber"></param>
|
/// <param name="phoneNumber"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task<bool> SendCodeAsync(string phoneNumber) => Task.FromResult(true);
|
public Task<SMSResult> SendCodeAsync(string phoneNumber) => Task.FromResult(new SMSResult() { Result = true });
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 验证验证码方法
|
/// 验证验证码方法
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Bootstrap.DataAccess;
|
using Bootstrap.DataAccess;
|
||||||
using Longbow.Web.Mvc;
|
using Longbow.Web.Mvc;
|
||||||
|
using Longbow.Web.SMS;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
@ -36,12 +37,14 @@ namespace Bootstrap.Admin.Api.SqlServer
|
||||||
public async void Put_Ok()
|
public async void Put_Ok()
|
||||||
{
|
{
|
||||||
var resq = await Client.PutAsync("?phone=", new StringContent(""));
|
var resq = await Client.PutAsync("?phone=", new StringContent(""));
|
||||||
var _token = await resq.Content.ReadAsStringAsync();
|
var payload = await resq.Content.ReadAsStringAsync();
|
||||||
Assert.Equal("false", _token);
|
var resp = System.Text.Json.JsonSerializer.Deserialize<SMSResult>(payload, new System.Text.Json.JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
|
||||||
|
Assert.False(resp.Result);
|
||||||
|
|
||||||
resq = await Client.PutAsync("?phone=18910001000", new StringContent(""));
|
resq = await Client.PutAsync("?phone=18910281024", new StringContent(""));
|
||||||
_token = await resq.Content.ReadAsStringAsync();
|
payload = await resq.Content.ReadAsStringAsync();
|
||||||
Assert.Equal("true", _token);
|
resp = System.Text.Json.JsonSerializer.Deserialize<SMSResult>(payload, new System.Text.Json.JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
|
||||||
|
Assert.True(resp.Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Error",
|
"Default": "Error",
|
||||||
|
@ -63,12 +63,19 @@
|
||||||
"SMSOptions": {
|
"SMSOptions": {
|
||||||
"CompanyCode": "<CompanyCode>",
|
"CompanyCode": "<CompanyCode>",
|
||||||
"MD5Key": "MD5Key",
|
"MD5Key": "MD5Key",
|
||||||
"Roles": [
|
"Roles": [ "Administrators" ],
|
||||||
"Administrators"
|
|
||||||
],
|
|
||||||
"HomePath": "/Admin/Profiles",
|
"HomePath": "/Admin/Profiles",
|
||||||
"App": "0"
|
"App": "0"
|
||||||
},
|
},
|
||||||
|
"TencentSMSOptions": {
|
||||||
|
"AppId": "<TencentAppId>",
|
||||||
|
"AppKey": "<TencentAppKey>",
|
||||||
|
"TplId": "<TencentTplId>",
|
||||||
|
"Sign": "<TencentSign>",
|
||||||
|
"Roles": [ "Default" ],
|
||||||
|
"HomePath": "/Admin/Profiles",
|
||||||
|
"App": "Demo"
|
||||||
|
},
|
||||||
"LongbowCache": {
|
"LongbowCache": {
|
||||||
"Enabled": false
|
"Enabled": false
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue