using EasyCaching.Core; using Microsoft.Extensions.Logging; using YD_Event.Application.Client.Dtos; namespace YD_Event.Application.Client; /// /// 微信小程序认证接口 /// [ApiDescriptionSettings("微信小程序接口")] public class OAuthController : IDynamicApiController { private readonly ISqlSugarRepository _appUserRepository; private readonly IEasyCachingProvider _cachingProvider; private readonly IIdGenerator _idGenerator; private readonly ILogger _logger; private const string SmsCodeCachePrefix = "sms:code:"; public OAuthController( ISqlSugarRepository appUserRepository, IEasyCachingProvider cachingProvider, IIdGenerator idGenerator, ILogger logger) { _appUserRepository = appUserRepository; _cachingProvider = cachingProvider; _idGenerator = idGenerator; _logger = logger; } /// /// 登录接口(支持账号密码登录和短信验证码登录两种方式) /// /// /// [HttpPost("login")] [AllowAnonymous] public async Task Login([FromBody] MiniProgramLoginInput input) { var isPasswordLogin = !string.IsNullOrEmpty(input.Password); var isSmsLogin = !string.IsNullOrEmpty(input.VerificationCode); if (!isPasswordLogin && !isSmsLogin) { throw Oops.Bah("请选择密码登录或短信验证码登录"); } if (isPasswordLogin && isSmsLogin) { throw Oops.Bah("请选择一种登录方式"); } var appUser = await _appUserRepository.GetFirstAsync(x => x.Mobile == input.Mobile); if (appUser == null) { throw Oops.Bah("用户不存在,请先注册"); } if (isPasswordLogin) { 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("密码错误"); } } else { var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}"; var cachedCodeResult = _cachingProvider.Get(cacheKey); string cachedCode = cachedCodeResult.Value; if (!cachedCodeResult.HasValue || cachedCode != input.VerificationCode) { throw Oops.Bah("验证码错误或已过期"); } _cachingProvider.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 }; } /// /// 注册接口 /// /// /// [HttpPost("register")] [AllowAnonymous] [UnitOfWork] public async Task Register([FromBody] MiniProgramRegisterInput input) { var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}"; var cachedCodeResult = _cachingProvider.Get(cacheKey); string cachedCode = cachedCodeResult.Value; if (!cachedCodeResult.HasValue || cachedCode != input.VerificationCode) { throw Oops.Bah("验证码错误或已过期"); } _cachingProvider.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 = 0 }; await _appUserRepository.InsertAsync(appUser); return new MiniProgramRegisterOutput { UserId = appUser.Id, Mobile = appUser.Mobile, NickName = appUser.NickName, RegisterTime = appUser.CreatedTime }; } /// /// 重置密码接口 /// /// /// [HttpPost("reset-password")] [AllowAnonymous] public async Task ResetPassword([FromBody] MiniProgramResetPasswordInput input) { var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}"; var cachedCodeResult = _cachingProvider.Get(cacheKey); string cachedCode = cachedCodeResult.Value; if (!cachedCodeResult.HasValue || cachedCode != input.VerificationCode) { throw Oops.Bah("验证码错误或已过期"); } _cachingProvider.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); } /// /// 生成自定义 Token /// private (string AccessToken, string RefreshToken) GenerateTokens(YD_Event.Core.Entities.AppUser appUser) { long uniqueId = _idGenerator.NewLong(); string accessToken = JWTEncryption.Encrypt(new Dictionary() { [AuthClaimsConst.AuthIdKey] = appUser.Id, [AuthClaimsConst.AccountKey] = appUser.Mobile, [AuthClaimsConst.UuidKey] = uniqueId, [AuthClaimsConst.AuthPlatformTypeKey] = AuthPlatformType.WeChatApplet }); string refreshToken = JWTEncryption.GenerateRefreshToken(accessToken); return (accessToken, refreshToken); } }