diff --git a/Yi.Framework.Net6/src/framework/Yi.Framework.Data/Extensions/DataSeedExtensions.cs b/Yi.Framework.Net6/src/framework/Yi.Framework.Data/Extensions/DataSeedExtensions.cs index b8180350..3e0fafbf 100644 --- a/Yi.Framework.Net6/src/framework/Yi.Framework.Data/Extensions/DataSeedExtensions.cs +++ b/Yi.Framework.Net6/src/framework/Yi.Framework.Data/Extensions/DataSeedExtensions.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; diff --git a/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunManager.cs b/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunManager.cs index 1de33228..07b248f5 100644 --- a/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunManager.cs +++ b/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunManager.cs @@ -15,11 +15,15 @@ namespace Yi.Framework.Sms.Aliyun public Client AliyunClient { get; set; } private ILogger _logger; private SmsAliyunOptions Options { get; set; } - public SmsAliyunManager(ILogger logger,IOptions options) + public SmsAliyunManager(ILogger logger, IOptions options) { - _logger = logger; - AliyunClient = CreateClient(Options.AccessKeyId, Options.AccessKeySecret); Options = options.Value; + if (Options.EnableFeature) + { + _logger = logger; + AliyunClient = CreateClient(Options.AccessKeyId, Options.AccessKeySecret); + } + } private static Client CreateClient(string accessKeyId, string accessKeySecret) diff --git a/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunOptions.cs b/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunOptions.cs index afe9ca7f..9ab63f3c 100644 --- a/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunOptions.cs +++ b/Yi.Framework.Net6/src/module/Yi.Framework.Sms.Aliyun/SmsAliyunOptions.cs @@ -12,5 +12,7 @@ namespace Yi.Framework.Sms.Aliyun public string AccessKeySecret { get; set; } public string SignName { get; set; } + + public bool EnableFeature { get; set; } = true; } } diff --git a/Yi.Framework.Net6/src/project/BBS/Yi.BBS.Web/appsettings.json b/Yi.Framework.Net6/src/project/BBS/Yi.BBS.Web/appsettings.json index dfccfb75..c41ff72f 100644 --- a/Yi.Framework.Net6/src/project/BBS/Yi.BBS.Web/appsettings.json +++ b/Yi.Framework.Net6/src/project/BBS/Yi.BBS.Web/appsettings.json @@ -16,7 +16,6 @@ "DbConnOptions": { "Url": "DataSource=yi-sqlsugar-dev.db", "DbType": "Sqlite", - "EnabledDbSeed": false, "EnabledReadWrite": false, "EnabledCodeFirst": false, "EntityAssembly": null, @@ -42,6 +41,7 @@ "SmsAliyunOptions": { "AccessKeyId": "", "AccessKeySecret": "", - "SignName": "" + "SignName": "", + "EnableFeature": false } } diff --git a/Yi.Framework.Net6/src/project/bbs/Yi.BBS.Web/appsettings.json b/Yi.Framework.Net6/src/project/bbs/Yi.BBS.Web/appsettings.json index dfccfb75..c41ff72f 100644 --- a/Yi.Framework.Net6/src/project/bbs/Yi.BBS.Web/appsettings.json +++ b/Yi.Framework.Net6/src/project/bbs/Yi.BBS.Web/appsettings.json @@ -16,7 +16,6 @@ "DbConnOptions": { "Url": "DataSource=yi-sqlsugar-dev.db", "DbType": "Sqlite", - "EnabledDbSeed": false, "EnabledReadWrite": false, "EnabledCodeFirst": false, "EntityAssembly": null, @@ -42,6 +41,7 @@ "SmsAliyunOptions": { "AccessKeyId": "", "AccessKeySecret": "", - "SignName": "" + "SignName": "", + "EnableFeature": false } } diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Identity/Dtos/Account/LoginInputVo.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Identity/Dtos/Account/LoginInputVo.cs index 10ef1d51..729e184c 100644 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Identity/Dtos/Account/LoginInputVo.cs +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Identity/Dtos/Account/LoginInputVo.cs @@ -11,8 +11,8 @@ namespace Yi.RBAC.Application.Contracts.Identity.Dtos.Account public string UserName { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; - public string? Uuid { get; set; } + public string Uuid { get; set; } - public string? Code { get; set; } + public string Code { get; set; } } } diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Identity/AccountService.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Identity/AccountService.cs index a16c85af..ae33d6cf 100644 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Identity/AccountService.cs +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Identity/AccountService.cs @@ -31,6 +31,9 @@ using Yi.RBAC.Domain.Shared.Identity.Etos; using System.Net.WebSockets; using Yi.Framework.Uow; using Yi.Framework.Caching; +using Yi.Framework.Sms.Aliyun; +using Microsoft.Extensions.Options; +using System.Text.RegularExpressions; namespace Yi.RBAC.Application.Identity { @@ -72,20 +75,38 @@ namespace Yi.RBAC.Application.Identity [Autowired] private CacheManager _cacheManager { get; set; } - /// - /// 效验图片登录验证码 - /// - private void ValidationCaptcha() - { + [Autowired] + private SmsAliyunManager _smsAliyunManager { get; set; } + [Autowired] + private IOptions _smsAliyunManagerOptions { get; set; } + + /// + /// 效验图片登录验证码,无需和账号绑定 + /// + private void ValidationImageCaptcha(LoginInputVo input) + { + //登录不想要验证码 ,不效验 + return; + var value = _cacheManager.Get($"Yi:Captcha:{input.Code}"); + if (value is not null && value.Equals(input.Uuid)) + { + return; + } + throw new UserFriendlyException("验证码错误"); } /// - /// 效验电话验证码 + /// 效验电话验证码,需要与电话号码绑定 /// - private void ValidationPhone() + private void ValidationPhoneCaptcha(RegisterDto input) { - + var value = _cacheManager.Get($"Yi:Phone:{input.Phone}"); + if (value is not null && value.Equals($"{input.Code}:{input.Uuid}")) + { + return; + } + throw new UserFriendlyException("验证码错误"); } /// @@ -101,7 +122,7 @@ namespace Yi.RBAC.Application.Identity } //效验验证码 - ValidationCaptcha(); + ValidationImageCaptcha(input); UserEntity user = new(); //登录成功 @@ -130,18 +151,70 @@ namespace Yi.RBAC.Application.Identity return new { Token = token }; } + /// + /// 生成验证码 + /// + /// + + [AllowAnonymous] + public CaptchaImageDto GetCaptchaImage() + { + var uuid = Guid.NewGuid(); + var code = _securityCode.GetRandomEnDigitalText(4); + //将uuid与code,Redis缓存中心化保存起来,登录根据uuid比对即可 + //10分钟过期 + _cacheManager.Set($"Yi:Captcha:{code}", uuid, new TimeSpan(0, 10, 0)); + var imgbyte = _securityCode.GetEnDigitalCodeByte(code); + return new CaptchaImageDto { Img = imgbyte, Code = code, Uuid = uuid }; + } + + /// + /// 验证电话号码 + /// + /// + private void ValidationPhone(string str_handset) + { + var res= Regex.IsMatch(str_handset, "^(0\\d{2,3}-?\\d{7,8}(-\\d{3,5}){0,1})|(((13[0-9])|(15([0-3]|[5-9]))|(18[0-9])|(17[0-9])|(14[0-9]))\\d{8})$"); + if (res == false) + { + throw new UserFriendlyException("手机号码格式错误!请检查"); + } + } + + /// /// 注册 手机验证码 /// /// - public object PostPhoneCaptchaImage(PhoneCaptchaImageDto input) + [AllowAnonymous] + public async Task PostCaptchaPhone(PhoneCaptchaImageDto input) { - var code = _securityCode.GetRandomEnDigitalText(4); - var uuid = Guid.NewGuid(); - _cacheManager.Set($"Yi:Phone:{input.Phone}", $"{code}:{uuid}", new TimeSpan(0, 10, 0)); + ValidationPhone(input.Phone); + var value = _cacheManager.Get($"Yi:Phone:{input.Phone}"); + + //防止暴刷 + if (value is not null) + { + throw new UserFriendlyException($"{input.Phone}已发送过验证码,10分钟后可重试"); + } //生成一个4位数的验证码 //发送短信,同时生成uuid //key: 电话号码 value:验证码+uuid + var code = _securityCode.GetRandomEnDigitalText(4); + var uuid = Guid.NewGuid(); + + //未开启短信验证,默认8888 + if (_smsAliyunManagerOptions.Value.EnableFeature) + { + await _smsAliyunManager.Send(input.Phone, code); + } + else + { + code = "8888"; + } + _cacheManager.Set($"Yi:Phone:{input.Phone}", $"{code}:{uuid}", new TimeSpan(0, 10, 0)); + + return new { Uuid = uuid }; } @@ -150,6 +223,7 @@ namespace Yi.RBAC.Application.Identity /// /// /// + [AllowAnonymous] public async Task PostRegisterAsync(RegisterDto input) { if (input.UserName == UserConst.Admin) @@ -166,7 +240,7 @@ namespace Yi.RBAC.Application.Identity throw new UserFriendlyException("密码需大于等于6位!"); } //效验验证码,根据电话号码获取 value,比对验证码已经uuid - ValidationPhone(); + ValidationPhoneCaptcha(input); @@ -253,23 +327,6 @@ namespace Yi.RBAC.Application.Identity return Task.FromResult(true); } - /// - /// 生成验证码 - /// - /// - - [AllowAnonymous] - public CaptchaImageDto GetCaptchaImage() - { - var uuid = Guid.NewGuid(); - var code = _securityCode.GetRandomEnDigitalText(4); - //将uuid与code,Redis缓存中心化保存起来,登录根据uuid比对即可 - //10分钟过期 - _cacheManager.Set($"Yi:Captcha:{code}", uuid, new TimeSpan(0, 10, 0)); - var imgbyte = _securityCode.GetEnDigitalCodeByte(code); - return new CaptchaImageDto { Img = imgbyte, Code = code, Uuid = uuid }; - } - /// /// 更新密码 /// diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Yi.RBAC.ApplicationSwaggerDoc.xml b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Yi.RBAC.ApplicationSwaggerDoc.xml index f701746a..4b6f37b8 100644 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Yi.RBAC.ApplicationSwaggerDoc.xml +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Yi.RBAC.ApplicationSwaggerDoc.xml @@ -4,14 +4,14 @@ Yi.RBAC.Application - + - 效验图片登录验证码 + 效验图片登录验证码,无需和账号绑定 - + - 效验电话验证码 + 效验电话验证码,需要与电话号码绑定 @@ -21,7 +21,19 @@ - + + + 生成验证码 + + + + + + 验证电话号码 + + + + 注册 手机验证码 @@ -53,12 +65,6 @@ - - - 生成验证码 - - - 更新密码