feat: 完善验证、注册开关

This commit is contained in:
橙子
2023-12-20 21:43:16 +08:00
parent 22d25fd67e
commit edcba7a35a
8 changed files with 1561 additions and 35 deletions

View File

@@ -42,6 +42,7 @@ namespace Yi.Framework.Rbac.Application.Services
private readonly ICaptcha _captcha;
private readonly IGuidGenerator _guidGenerator;
private readonly RbacOptions _rbacOptions;
private readonly IAliyunManger _aliyunManger;
public AccountService(IUserRepository userRepository,
ICurrentUser currentUser,
AccountManager accountManager,
@@ -52,7 +53,8 @@ namespace Yi.Framework.Rbac.Application.Services
IDistributedCache<CaptchaPhoneCacheItem, CaptchaPhoneCacheKey> phoneCache,
ICaptcha captcha,
IGuidGenerator guidGenerator,
IOptions<RbacOptions> options)
IOptions<RbacOptions> options,
IAliyunManger aliyunManger)
{
_userRepository = userRepository;
_currentUser = currentUser;
@@ -65,6 +67,7 @@ namespace Yi.Framework.Rbac.Application.Services
_captcha = captcha;
_guidGenerator = guidGenerator;
_rbacOptions = options.Value;
_aliyunManger = aliyunManger;
}
@@ -92,20 +95,7 @@ namespace Yi.Framework.Rbac.Application.Services
}
}
/// <summary>
/// 效验电话验证码,需要与电话号码绑定
/// </summary>
private void ValidationPhoneCaptcha(RegisterDto input)
{
//var value = _memoryCache.Get<string>($"Yi:Phone:{input.Phone}");
//if (value is not null && value.Equals($"{input.Code}"))
//{
// //成功,需要清空
// _memoryCache.Remove($"Yi:Phone:{input.Phone}");
// return;
//}
//throw new UserFriendlyException("验证码错误");
}
/// <summary>
/// 登录
@@ -228,19 +218,9 @@ namespace Yi.Framework.Rbac.Application.Services
//生成一个4位数的验证码
//发送短信同时生成uuid
////key 电话号码 value:验证码+uuid
//var code = _securityCode.GetRandomEnDigitalText(4);
var code = Guid.NewGuid().ToString().Substring(0, 4);
var uuid = Guid.NewGuid();
//未开启短信验证默认8888
//if (_smsAliyunManagerOptions.Value.EnableFeature)
//{
// await _smsAliyunManager.Send(input.Phone, code);
//}
//else
//{
var code = "8888";
//}
//_memoryCache.Set($"Yi:Phone:{input.Phone}", $"{code}", new TimeSpan(0, 10, 0));
await _aliyunManger.SendSmsAsync(input.Phone, code);
await _phoneCache.SetAsync(new CaptchaPhoneCacheKey(input.Phone), new CaptchaPhoneCacheItem(code), new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes(10) });
return new
@@ -249,6 +229,22 @@ namespace Yi.Framework.Rbac.Application.Services
};
}
/// <summary>
/// 效验电话验证码,需要与电话号码绑定
/// </summary>
private async Task ValidationPhoneCaptchaAsync(RegisterDto input)
{
var value = await _phoneCache.GetAsync(new CaptchaPhoneCacheKey(input.Phone.ToString()));
if (value is not null && value.Equals($"{input.Code}"))
{
//成功,需要清空
await _phoneCache.RemoveAsync(new CaptchaPhoneCacheKey(input.Phone.ToString()));
return;
}
throw new UserFriendlyException("验证码错误");
}
/// <summary>
/// 注册,需要验证码通过
/// </summary>
@@ -258,6 +254,11 @@ namespace Yi.Framework.Rbac.Application.Services
[UnitOfWork]
public async Task<object> PostRegisterAsync(RegisterDto input)
{
if (_rbacOptions.EnableRegister == false)
{
throw new UserFriendlyException("该系统暂未开放注册功能");
}
if (input.UserName == UserConst.Admin)
{
throw new UserFriendlyException("用户名无效注册!");
@@ -272,15 +273,13 @@ namespace Yi.Framework.Rbac.Application.Services
throw new UserFriendlyException("密码需大于等于6位");
}
//效验验证码,根据电话号码获取 value比对验证码已经uuid
ValidationPhoneCaptcha(input);
await ValidationPhoneCaptchaAsync(input);
//输入的用户名与电话号码都不能在数据库中存在
UserEntity user = new();
var isExist = await _userRepository.IsAnyAsync(x =>
x.UserName == input.UserName
|| x.Phone == input.Phone);
var isExist = await _userRepository.IsAnyAsync(x =>x.UserName == input.UserName|| x.Phone == input.Phone);
if (isExist)
{
throw new UserFriendlyException("用户已存在,注册失败");

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Rbac.Domain.Shared.Options
{
public class AliyunOptions
{
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public AliyunSms Sms { get; set; }
}
public class AliyunSms
{
public string SignName { get; set; }
public string TemplateCode { get; set; }
}
}

View File

@@ -17,5 +17,10 @@ namespace Yi.Framework.Rbac.Domain.Shared.Options
/// 是否开启登录验证码
/// </summary>
public bool EnableCaptcha { get; set; } = false;
/// <summary>
/// 是否开启用户注册功能
/// </summary>
public bool EnableRegister { get; set; } = false;
}
}

View File

@@ -0,0 +1,69 @@
using AlibabaCloud.SDK.Dysmsapi20170525;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Domain.Services;
using Yi.Framework.Rbac.Domain.Shared.Options;
namespace Yi.Framework.Rbac.Domain.Managers
{
public class AliyunManger : DomainService, IAliyunManger
{
private ILogger<AliyunManger> _logger;
private AliyunOptions Options { get; set; }
public AliyunManger(ILogger<AliyunManger> logger, IOptions<AliyunOptions> options)
{
Options = options.Value;
_logger = logger;
}
private Client CreateClient()
{
AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
{
// 必填,您的 AccessKey ID
AccessKeyId = Options.AccessKeyId,
// 必填,您的 AccessKey Secret
AccessKeySecret = Options.AccessKeySecret,
};
// 访问的域名
config.Endpoint = "dysmsapi.aliyuncs.com";
return new Client(config);
}
/// <summary>
/// 发送短信
/// </summary>
/// <param name="phoneNumbers"></param>
/// <param name="code"></param>
/// <returns></returns>
public async Task SendSmsAsync(string phoneNumbers, string code)
{
try
{
var _aliyunClient = CreateClient();
AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest sendSmsRequest = new AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest
{
PhoneNumbers = phoneNumbers,
SignName = Options.Sms.SignName,
TemplateCode = Options.Sms.TemplateCode,
TemplateParam = System.Text.Json.JsonSerializer.Serialize(new { code })
};
var response = await _aliyunClient.SendSmsAsync(sendSmsRequest);
}
catch (Exception _error)
{
_logger.LogError(_error, "阿里云短信发送错误:" + _error.Message);
}
}
}
public interface IAliyunManger
{
Task SendSmsAsync(string phoneNumbers, string code);
}
}

View File

@@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="2.0.24" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="UAParser" Version="3.1.47" />