198 lines
6.5 KiB
C#
198 lines
6.5 KiB
C#
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Logging;
|
|
using YD_Event.Application.Client.Dtos;
|
|
|
|
namespace YD_Event.Application.Client;
|
|
|
|
/// <summary>
|
|
/// 微信小程序认证接口
|
|
/// </summary>
|
|
[ApiDescriptionSettings("微信小程序接口")]
|
|
public class OAuthController : IDynamicApiController
|
|
{
|
|
private readonly ISqlSugarRepository<YD_Event.Core.Entities.AppUser> _appUserRepository;
|
|
private readonly IMemoryCache _memoryCache;
|
|
private readonly IIdGenerator _idGenerator;
|
|
private readonly ILogger<OAuthController> _logger;
|
|
|
|
private const string SmsCodeCachePrefix = "sms:code:";
|
|
|
|
public OAuthController(
|
|
ISqlSugarRepository<YD_Event.Core.Entities.AppUser> appUserRepository,
|
|
IMemoryCache memoryCache,
|
|
IIdGenerator idGenerator,
|
|
ILogger<OAuthController> logger)
|
|
{
|
|
_appUserRepository = appUserRepository;
|
|
_memoryCache = memoryCache;
|
|
_idGenerator = idGenerator;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 登录接口
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("login")]
|
|
[AllowAnonymous]
|
|
public async Task<MiniProgramLoginOutput> Login([FromBody] MiniProgramLoginInput input)
|
|
{
|
|
if (string.IsNullOrEmpty(input.Password) && string.IsNullOrEmpty(input.VerificationCode))
|
|
{
|
|
throw Oops.Bah("密码和验证码至少提供一个");
|
|
}
|
|
|
|
var appUser = await _appUserRepository.GetFirstAsync(x => x.Mobile == input.Mobile);
|
|
if (appUser == null)
|
|
{
|
|
throw Oops.Bah("用户不存在,请先注册");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(input.Password))
|
|
{
|
|
if (string.IsNullOrEmpty(appUser.Password))
|
|
{
|
|
throw Oops.Bah("该用户未设置密码,请使用验证码登录");
|
|
}
|
|
var encryptedPassword = MD5Encryption.Encrypt($"{_idGenerator.Encode(appUser.Id)}{input.Password}");
|
|
if (appUser.Password != encryptedPassword)
|
|
{
|
|
throw Oops.Bah("密码错误");
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(input.VerificationCode))
|
|
{
|
|
var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}";
|
|
string cachedCode = null;
|
|
if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode)
|
|
{
|
|
throw Oops.Bah("验证码错误或已过期");
|
|
}
|
|
_memoryCache.Remove(cacheKey);
|
|
}
|
|
|
|
(string accessToken, string refreshToken) = GenerateTokens(appUser);
|
|
|
|
var userInfo = new
|
|
{
|
|
appUser.Name,
|
|
appUser.Id,
|
|
appUser.Mobile,
|
|
appUser.Avatar,
|
|
appUser.NickName
|
|
};
|
|
|
|
return new MiniProgramLoginOutput
|
|
{
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresIn = 7200,
|
|
UserInfo = userInfo
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 注册接口
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("register")]
|
|
[AllowAnonymous]
|
|
[UnitOfWork]
|
|
public async Task<MiniProgramRegisterOutput> Register([FromBody] MiniProgramRegisterInput input)
|
|
{
|
|
var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}";
|
|
string cachedCode = null;
|
|
if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode)
|
|
{
|
|
throw Oops.Bah("验证码错误或已过期");
|
|
}
|
|
_memoryCache.Remove(cacheKey);
|
|
|
|
if (await _appUserRepository.IsAnyAsync(x => x.Mobile == input.Mobile))
|
|
{
|
|
throw Oops.Bah("该手机号已注册");
|
|
}
|
|
|
|
long appUserId = _idGenerator.NewLong();
|
|
var encryptedPassword = MD5Encryption.Encrypt($"{_idGenerator.Encode(appUserId)}{input.Password}");
|
|
|
|
var appUser = new YD_Event.Core.Entities.AppUser
|
|
{
|
|
Id = appUserId,
|
|
Name = input.NickName ?? input.Mobile,
|
|
NickName = input.NickName,
|
|
Avatar = input.Avatar,
|
|
Gender = Gender.Unknown,
|
|
Mobile = input.Mobile,
|
|
Password = encryptedPassword,
|
|
PersonType = PersonType.User,
|
|
Status = AvailabilityStatus.Enable,
|
|
AuditStatus = AuditStatus.Pass,
|
|
CreatedTime = DateTime.Now,
|
|
CreatedUserId = appUserId
|
|
};
|
|
await _appUserRepository.InsertAsync(appUser);
|
|
|
|
return new MiniProgramRegisterOutput
|
|
{
|
|
UserId = appUser.Id,
|
|
Mobile = appUser.Mobile,
|
|
NickName = appUser.NickName,
|
|
RegisterTime = appUser.CreatedTime
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 重置密码接口
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("reset-password")]
|
|
[AllowAnonymous]
|
|
public async Task ResetPassword([FromBody] MiniProgramResetPasswordInput input)
|
|
{
|
|
var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}";
|
|
string cachedCode = null;
|
|
if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode)
|
|
{
|
|
throw Oops.Bah("验证码错误或已过期");
|
|
}
|
|
_memoryCache.Remove(cacheKey);
|
|
|
|
var appUser = await _appUserRepository.GetFirstAsync(x => x.Mobile == input.Mobile);
|
|
if (appUser == null)
|
|
{
|
|
throw Oops.Bah("用户不存在");
|
|
}
|
|
|
|
var encryptedPassword = MD5Encryption.Encrypt($"{_idGenerator.Encode(appUser.Id)}{input.NewPassword}");
|
|
appUser.Password = encryptedPassword;
|
|
appUser.UpdatedTime = DateTime.Now;
|
|
appUser.UpdatedUserId = appUser.Id;
|
|
|
|
await _appUserRepository.UpdateAsync(appUser);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成自定义 Token
|
|
/// </summary>
|
|
private (string AccessToken, string RefreshToken) GenerateTokens(YD_Event.Core.Entities.AppUser appUser)
|
|
{
|
|
long uniqueId = _idGenerator.NewLong();
|
|
string accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>()
|
|
{
|
|
[AuthClaimsConst.AuthIdKey] = appUser.Id,
|
|
[AuthClaimsConst.AccountKey] = appUser.Mobile,
|
|
[AuthClaimsConst.UuidKey] = uniqueId,
|
|
[AuthClaimsConst.AuthPlatformTypeKey] = AuthPlatformType.WeChatApplet
|
|
});
|
|
|
|
string refreshToken = JWTEncryption.GenerateRefreshToken(accessToken);
|
|
|
|
return (accessToken, refreshToken);
|
|
}
|
|
}
|