You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.7 KiB
132 lines
3.7 KiB
using System;
|
|
using System.Threading.Tasks;
|
|
using CellularManagement.Domain.Services;
|
|
using Microsoft.Extensions.Caching.Distributed;
|
|
using System.Text.Json;
|
|
|
|
namespace CellularManagement.Infrastructure.Services;
|
|
|
|
/// <summary>
|
|
/// 邮箱验证码服务
|
|
/// 提供验证码生成、发送和验证的具体实现
|
|
/// </summary>
|
|
public class EmailVerificationService : IEmailVerificationService
|
|
{
|
|
private readonly IEmailService _emailService;
|
|
private readonly IDistributedCache _cache;
|
|
private const string CacheKeyPrefix = "EmailVerification_";
|
|
private const int VerificationCodeLength = 6;
|
|
private const int VerificationCodeExpirationMinutes = 5;
|
|
|
|
/// <summary>
|
|
/// 构造函数
|
|
/// </summary>
|
|
/// <param name="emailService">邮箱服务</param>
|
|
/// <param name="cache">分布式缓存</param>
|
|
public EmailVerificationService(IEmailService emailService, IDistributedCache cache)
|
|
{
|
|
_emailService = emailService;
|
|
_cache = cache;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成并发送验证码
|
|
/// </summary>
|
|
/// <param name="email">邮箱地址</param>
|
|
/// <returns>是否发送成功</returns>
|
|
public async Task<bool> GenerateAndSendVerificationCodeAsync(string email)
|
|
{
|
|
if (!_emailService.ValidateEmail(email))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 生成6位数字验证码
|
|
var verificationCode = GenerateVerificationCode();
|
|
|
|
// 将验证码保存到缓存
|
|
var cacheKey = $"{CacheKeyPrefix}{email}";
|
|
var cacheValue = JsonSerializer.Serialize(new
|
|
{
|
|
Code = verificationCode,
|
|
CreatedAt = DateTime.UtcNow
|
|
});
|
|
|
|
await _cache.SetStringAsync(
|
|
cacheKey,
|
|
cacheValue,
|
|
new DistributedCacheEntryOptions
|
|
{
|
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(VerificationCodeExpirationMinutes)
|
|
});
|
|
|
|
// 发送验证码邮件
|
|
return await _emailService.SendVerificationCodeAsync(email, verificationCode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 验证验证码
|
|
/// </summary>
|
|
/// <param name="email">邮箱地址</param>
|
|
/// <param name="code">验证码</param>
|
|
/// <returns>验证结果</returns>
|
|
public async Task<bool> VerifyCodeAsync(string email, string code)
|
|
{
|
|
var cacheKey = $"{CacheKeyPrefix}{email}";
|
|
var cachedValue = await _cache.GetStringAsync(cacheKey);
|
|
|
|
if (string.IsNullOrEmpty(cachedValue))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var verificationData = JsonSerializer.Deserialize<VerificationData>(cachedValue);
|
|
|
|
if (verificationData == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 验证码是否过期
|
|
if (DateTime.UtcNow - verificationData.CreatedAt > TimeSpan.FromMinutes(VerificationCodeExpirationMinutes))
|
|
{
|
|
await _cache.RemoveAsync(cacheKey);
|
|
return false;
|
|
}
|
|
|
|
// 验证码是否匹配
|
|
if (verificationData.Code != code)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 验证成功后删除缓存
|
|
await _cache.RemoveAsync(cacheKey);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成验证码
|
|
/// </summary>
|
|
private string GenerateVerificationCode()
|
|
{
|
|
var random = new Random();
|
|
var code = string.Empty;
|
|
|
|
for (int i = 0; i < VerificationCodeLength; i++)
|
|
{
|
|
code += random.Next(0, 10).ToString();
|
|
}
|
|
|
|
return code;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 验证数据
|
|
/// </summary>
|
|
private class VerificationData
|
|
{
|
|
public string Code { get; set; } = string.Empty;
|
|
public DateTime CreatedAt { get; set; }
|
|
}
|
|
}
|