feat: 完成微信小程序账户应用服务
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\common.props" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
||||
<PackageReference Include="Volo.Abp.Caching" Version="$(AbpVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Volo.Abp.Caching;
|
||||
using Yi.Framework.Core;
|
||||
using Yi.Framework.WeChat.MiniProgram.Token;
|
||||
|
||||
namespace Yi.Framework.WeChat.MiniProgram;
|
||||
|
||||
[DependsOn(typeof(YiFrameworkCoreModule),
|
||||
typeof(AbpCachingModule))]
|
||||
public class YiFrameworkWeChatMiniProgramModule: AbpModule
|
||||
{
|
||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||
{
|
||||
var services = context.Services;
|
||||
var configuration = context.Services.GetConfiguration();
|
||||
Configure<WeChatMiniProgramOptions>(configuration.GetSection("WeChatMiniProgram"));
|
||||
services.AddSingleton<IMiniProgramToken, CacheMiniProgramToken>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Account;
|
||||
|
||||
public class BindInput
|
||||
{
|
||||
public string JsCode { get; set; }
|
||||
|
||||
public long Phone { get; set; }
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
public class LoginInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 微信小程序code
|
||||
/// 微信小程序jscode
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
public string JsCode { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
namespace Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Account;
|
||||
|
||||
public class RegisterInput
|
||||
{
|
||||
|
||||
//电话号码,根据code的表示来获取
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 唯一标识码
|
||||
/// </summary>
|
||||
public string? Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 电话
|
||||
/// </summary>
|
||||
public long Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string? Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
public string? Nick{ get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 微信小程序code
|
||||
/// </summary>
|
||||
public string JsCode { get; set; }
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using Volo.Abp.Application.Services;
|
||||
|
||||
namespace Yi.Framework.DigitalCollectibles.Application.Services.Account;
|
||||
|
||||
public class CollectiblesAccountService: ApplicationService
|
||||
{
|
||||
/// <summary>
|
||||
/// 小程序登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task PostLoginAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//根据code去获取wxid
|
||||
//判断wxid中是否有对应的userid关系
|
||||
//果然有,直接根据userid返回该用户token
|
||||
//如果没有,返回结果即可
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 小程序绑定账号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task PostBindAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//根据code去获取wxid
|
||||
//校验手机号
|
||||
//根据手机号查询用户信息
|
||||
//将wxid和用户user绑定
|
||||
}
|
||||
|
||||
//小程序注册
|
||||
public Task PostRegisterAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//走普通注册流程
|
||||
//同时再加一个小程序绑定即可
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Account;
|
||||
using Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
|
||||
using Yi.Framework.DigitalCollectibles.Domain.Shared.Enums;
|
||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Enums;
|
||||
using Yi.Framework.WeChat.MiniProgram;
|
||||
using Yi.Framework.WeChat.MiniProgram.HttpModels;
|
||||
|
||||
namespace Yi.Framework.DigitalCollectibles.Application.Services.Account;
|
||||
|
||||
/// <summary>
|
||||
/// 微信小程序账户应用服务
|
||||
/// </summary>
|
||||
public class WeChatMiniProgramAccountService : ApplicationService
|
||||
{
|
||||
private readonly IWeChatMiniProgramManager _weChatMiniProgramManager;
|
||||
private readonly IAuthService _authService;
|
||||
private readonly IAccountService _accountService;
|
||||
|
||||
public WeChatMiniProgramAccountService(IWeChatMiniProgramManager weChatMiniProgramManager, IAuthService authService,
|
||||
IAccountService accountService)
|
||||
{
|
||||
_weChatMiniProgramManager = weChatMiniProgramManager;
|
||||
_authService = authService;
|
||||
_accountService = accountService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用小程序jsCode登录意社区账号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("wechat/mini-program/account/login")]
|
||||
public async Task<LoginOutput> PostLoginAsync(LoginInput intput)
|
||||
{
|
||||
var output = new LoginOutput();
|
||||
//根据code去获取wxid
|
||||
//判断wxid中是否有对应的userid关系
|
||||
//果然有,直接根据userid返回该用户token
|
||||
//如果没有,返回结果即可
|
||||
var openId = (await _weChatMiniProgramManager.Code2SessionAsync(new Code2SessionInput(intput.JsCode))).openid;
|
||||
|
||||
var authInfo = await _authService.TryGetByOpenIdAsync(openId, AuthTypeConst.WeChatMiniProgram);
|
||||
if (authInfo is null)
|
||||
{
|
||||
output.Result = LoginResultEnum.Error;
|
||||
}
|
||||
|
||||
//根据用户id获取到用户信息
|
||||
var result = await _accountService.PostLoginAsync(authInfo.UserId);
|
||||
output.Result = LoginResultEnum.Success;
|
||||
output.Token = result.Token;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将小程序第三方授权绑定给意社区账号
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
[HttpPost("wechat/mini-program/account/bind")]
|
||||
public async Task PostBindAsync(BindInput input)
|
||||
{
|
||||
//校验手机号与验证码
|
||||
//根据手机号查询用户信息
|
||||
//根据code去获取wxid
|
||||
//将wxid和用户user绑定
|
||||
var userInfo = await _accountService.GetAsync(null, input.Phone);
|
||||
if (userInfo is null)
|
||||
{
|
||||
throw new UserFriendlyException("该手机号未被注册,无法绑定微信小程序");
|
||||
}
|
||||
|
||||
//验证手机号的验证码
|
||||
await _accountService.PostCaptchaPhoneAsync(ValidationPhoneTypeEnum.Register, new PhoneCaptchaImageDto
|
||||
{
|
||||
Phone = input.Phone.ToString()
|
||||
});
|
||||
|
||||
var openId = (await _weChatMiniProgramManager.Code2SessionAsync(new Code2SessionInput(input.JsCode))).openid;
|
||||
|
||||
|
||||
await PostBindToAuthAsync(userInfo.User.Id, openId, userInfo.User.UserName);
|
||||
}
|
||||
|
||||
private async Task PostBindToAuthAsync(Guid userId, string openId, string? name = null)
|
||||
{
|
||||
await _authService.CreateAsync(new AuthCreateOrUpdateInputDto
|
||||
{
|
||||
UserId = userId,
|
||||
OpenId = openId,
|
||||
Name = name ?? "未知",
|
||||
AuthType = AuthTypeConst.WeChatMiniProgram
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用小程序去注册意社区账号
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
[HttpPost("wechat/mini-program/account/register")]
|
||||
public async Task PostRegisterAsync(RegisterInput input)
|
||||
{
|
||||
//走普通注册流程
|
||||
//同时再加一个小程序绑定即可
|
||||
await _accountService.PostRegisterAsync(new RegisterDto
|
||||
{
|
||||
UserName = input.UserName,
|
||||
Password = input.Password,
|
||||
Uuid = input.Uuid,
|
||||
Phone = input.Phone,
|
||||
Code = input.Code,
|
||||
Nick = input.Nick
|
||||
});
|
||||
var userInfo = await _accountService.GetAsync(input.UserName, null);
|
||||
var openId = (await _weChatMiniProgramManager.Code2SessionAsync(new Code2SessionInput(input.JsCode))).openid;
|
||||
await PostBindToAuthAsync(userInfo.User.Id, openId, userInfo.User.UserName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
|
||||
|
||||
public class AuthTypeConst
|
||||
{
|
||||
public const string WeChatMiniProgram = "WeChatMiniProgram";
|
||||
}
|
||||
@@ -10,10 +10,12 @@
|
||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj" />
|
||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" />
|
||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.SqlSugarCore.Abstractions\Yi.Framework.SqlSugarCore.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.WeChat.MiniProgram\Yi.Framework.WeChat.MiniProgram.csproj" />
|
||||
<ProjectReference Include="..\..\setting-management\Yi.Framework.SettingManagement.Domain\Yi.Framework.SettingManagement.Domain.csproj" />
|
||||
<ProjectReference Include="..\Yi.Framework.DigitalCollectibles.Domain.Shared\Yi.Framework.DigitalCollectibles.Domain.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="EventHandlers\" />
|
||||
<Folder Include="Repositories\" />
|
||||
|
||||
@@ -4,12 +4,14 @@ using Volo.Abp.Modularity;
|
||||
using Yi.Framework.DigitalCollectibles.Domain.Shared;
|
||||
using Yi.Framework.Mapster;
|
||||
using Yi.Framework.SettingManagement.Domain;
|
||||
using Yi.Framework.WeChat.MiniProgram;
|
||||
|
||||
namespace Yi.Framework.DigitalCollectibles.Domain
|
||||
{
|
||||
[DependsOn(
|
||||
typeof(YiFrameworkDigitalCollectiblesDomainSharedModule),
|
||||
|
||||
|
||||
typeof(YiFrameworkWeChatMiniProgramModule),
|
||||
typeof(YiFrameworkSettingManagementDomainModule),
|
||||
typeof(YiFrameworkMapsterModule),
|
||||
typeof(AbpDddDomainModule),
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
|
||||
public class AuthCreateOrUpdateInputDto
|
||||
{
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
public string OpenId { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string AuthType { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
|
||||
public class LoginOutputDto
|
||||
{
|
||||
public string Token { get; set; }
|
||||
public string RefreshToken { get; set; }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Volo.Abp.Application.Services;
|
||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Dtos;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Enums;
|
||||
|
||||
namespace Yi.Framework.Rbac.Application.Contracts.IServices
|
||||
{
|
||||
@@ -8,8 +9,29 @@ namespace Yi.Framework.Rbac.Application.Contracts.IServices
|
||||
{
|
||||
Task<UserRoleMenuDto> GetAsync();
|
||||
Task<CaptchaImageDto> GetCaptchaImageAsync();
|
||||
Task<object> PostLoginAsync(LoginInputVo input);
|
||||
Task<LoginOutputDto> PostLoginAsync(LoginInputVo input);
|
||||
Task PostRegisterAsync(RegisterDto input);
|
||||
Task<bool> RestPasswordAsync(Guid userId, RestPasswordDto input);
|
||||
|
||||
/// <summary>
|
||||
/// 提供其他服务使用,根据用户id,直接返回token
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<LoginOutputDto> PostLoginAsync(Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// 根据信息查询用户,可能为空,代表该用户不存在或禁用
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="phone"></param>
|
||||
/// <returns></returns>
|
||||
Task<UserRoleMenuDto?> GetAsync(string? userName,long? phone);
|
||||
|
||||
/// <summary>
|
||||
/// 手机验证码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<object> PostCaptchaPhoneAsync(ValidationPhoneTypeEnum validationPhoneType,
|
||||
PhoneCaptchaImageDto input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
|
||||
namespace Yi.Framework.Rbac.Application.Contracts.IServices;
|
||||
|
||||
public interface IAuthService
|
||||
{
|
||||
Task<AuthOutputDto?> TryGetByOpenIdAsync(string openId, string authType);
|
||||
Task<AuthOutputDto> CreateAsync(AuthCreateOrUpdateInputDto input);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
public async Task<object> PostLoginAsync(LoginInputVo input)
|
||||
public async Task<LoginOutputDto> PostLoginAsync(LoginInputVo input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input.Password) || string.IsNullOrEmpty(input.UserName))
|
||||
{
|
||||
@@ -115,10 +115,21 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
//校验
|
||||
await _accountManager.LoginValidationAsync(input.UserName, input.Password, x => user = x);
|
||||
|
||||
return await PostLoginAsync(user.Id);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 提供其他服务使用,根据用户id,直接返回token
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[RemoteService(isEnabled: false)]
|
||||
public async Task<LoginOutputDto> PostLoginAsync(Guid userId)
|
||||
{
|
||||
var userInfo = new UserRoleMenuDto();
|
||||
//获取token
|
||||
var accessToken = await _accountManager.GetTokenByUserIdAsync(user.Id, (info) => userInfo = info);
|
||||
var refreshToken = _accountManager.CreateRefreshToken(user.Id);
|
||||
var accessToken = await _accountManager.GetTokenByUserIdAsync(userId, (info) => userInfo = info);
|
||||
var refreshToken = _accountManager.CreateRefreshToken(userId);
|
||||
|
||||
//这里抛出一个登录的事件,也可以在全部流程走完,在应用层组装
|
||||
if (_httpContextAccessor.HttpContext is not null)
|
||||
@@ -130,10 +141,9 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
await LocalEventBus.PublishAsync(loginEto);
|
||||
}
|
||||
|
||||
return new { Token = accessToken, RefreshToken = refreshToken };
|
||||
return new LoginOutputDto { Token = accessToken, RefreshToken = refreshToken };
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 刷新token
|
||||
/// </summary>
|
||||
@@ -158,7 +168,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
var uuid = _guidGenerator.Create();
|
||||
var captcha = _captcha.Generate(uuid.ToString());
|
||||
var enableCaptcha = _rbacOptions.EnableCaptcha;
|
||||
return new CaptchaImageDto { Img = captcha.Bytes, Uuid = uuid,IsEnableCaptcha= enableCaptcha };
|
||||
return new CaptchaImageDto { Img = captcha.Bytes, Uuid = uuid, IsEnableCaptcha = enableCaptcha };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -202,17 +212,19 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
/// 手机验证码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<object> PostCaptchaPhoneAsync(ValidationPhoneTypeEnum validationPhoneType,
|
||||
public async Task<object> PostCaptchaPhoneAsync(ValidationPhoneTypeEnum validationPhoneType,
|
||||
PhoneCaptchaImageDto input)
|
||||
{
|
||||
await ValidationPhone(input.Phone);
|
||||
|
||||
|
||||
//注册的手机号验证,是不能已经注册过的
|
||||
if (validationPhoneType == ValidationPhoneTypeEnum.Register&& await _userRepository.IsAnyAsync(x => x.Phone.ToString() == input.Phone))
|
||||
{
|
||||
throw new UserFriendlyException("该手机号已被注册!");
|
||||
}
|
||||
|
||||
//这里为了统一,绑定流程,不在次校验,而是在注册时校验
|
||||
// if (validationPhoneType == ValidationPhoneTypeEnum.Register &&
|
||||
// await _userRepository.IsAnyAsync(x => x.Phone.ToString() == input.Phone))
|
||||
// {
|
||||
// throw new UserFriendlyException("该手机号已被注册!");
|
||||
// }
|
||||
|
||||
var value = await _phoneCache.GetAsync(new CaptchaPhoneCacheKey(validationPhoneType, input.Phone));
|
||||
|
||||
//防止暴刷
|
||||
@@ -264,7 +276,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
{
|
||||
//校验验证码,根据电话号码获取 value,比对验证码已经uuid
|
||||
await ValidationPhoneCaptchaAsync(ValidationPhoneTypeEnum.RetrievePassword, input.Phone, input.Code);
|
||||
|
||||
|
||||
var entity = await _userRepository.GetFirstAsync(x => x.Phone == input.Phone);
|
||||
if (entity is null)
|
||||
{
|
||||
@@ -272,7 +284,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
}
|
||||
|
||||
await _accountManager.RestPasswordAsync(entity.Id, input.Password);
|
||||
|
||||
|
||||
return entity.UserName;
|
||||
}
|
||||
|
||||
@@ -322,6 +334,30 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
return output;
|
||||
}
|
||||
|
||||
[RemoteService(isEnabled: false)]
|
||||
public async Task<UserRoleMenuDto?> GetAsync(string? userName, long? phone)
|
||||
{
|
||||
var user = await _userRepository._DbQueryable
|
||||
.WhereIF(userName is not null, x => x.UserName == userName)
|
||||
.WhereIF(phone is not null, x => x.Phone == phone)
|
||||
.Where(x => x.State == true)
|
||||
.FirstAsync();
|
||||
|
||||
//该用户不存在
|
||||
if (user is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//注意用户名大小写数据库不敏感问题
|
||||
if (userName is not null && user.UserName.Equals(userName))
|
||||
{
|
||||
throw new UserFriendlyException($"该用户名不存在或已禁用-{userName}");
|
||||
}
|
||||
|
||||
var output = await _userManager.GetInfoAsync(user.Id);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前登录用户的前端路由
|
||||
@@ -430,7 +466,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
/// <returns></returns>
|
||||
public async Task<bool> UpdateIconAsync(UpdateIconDto input)
|
||||
{
|
||||
Guid userId=input.UserId == null?_currentUser.GetId():input.UserId.Value;
|
||||
Guid userId = input.UserId == null ? _currentUser.GetId() : input.UserId.Value;
|
||||
|
||||
var entity = await _userRepository.GetByIdAsync(userId);
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ using SqlSugar;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Users;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
||||
using Yi.Framework.Rbac.Domain.Authorization;
|
||||
using Yi.Framework.Rbac.Domain.Managers;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
@@ -18,13 +20,17 @@ namespace Yi.Framework.Rbac.Application.Services.Authentication
|
||||
/// <summary>
|
||||
/// 第三方授权服务
|
||||
/// </summary>
|
||||
public class AuthService : YiCrudAppService<AuthAggregateRoot, AuthOutputDto, Guid, AuthGetListInput>
|
||||
public class AuthService :
|
||||
YiCrudAppService<AuthAggregateRoot, AuthOutputDto, Guid, AuthGetListInput, AuthCreateOrUpdateInputDto>,
|
||||
IAuthService
|
||||
{
|
||||
private HttpContext HttpContext { get; set; }
|
||||
private ILogger<AuthService> _logger;
|
||||
private ISqlSugarRepository<AuthAggregateRoot, Guid> _repository;
|
||||
private IAccountManager _accountManager;
|
||||
public AuthService(IAccountManager accountManager, IHttpContextAccessor httpContextAccessor, ILogger<AuthService> logger, ISqlSugarRepository<AuthAggregateRoot, Guid> repository) : base(repository)
|
||||
|
||||
public AuthService(IAccountManager accountManager, IHttpContextAccessor httpContextAccessor,
|
||||
ILogger<AuthService> logger, ISqlSugarRepository<AuthAggregateRoot, Guid> repository) : base(repository)
|
||||
{
|
||||
_logger = logger;
|
||||
HttpContext = httpContextAccessor.HttpContext ?? throw new ApplicationException("未注册Http");
|
||||
@@ -49,8 +55,9 @@ namespace Yi.Framework.Rbac.Application.Services.Authentication
|
||||
{
|
||||
throw new UserFriendlyException("第三方登录失败,请先注册后,在个人中心进行绑定该第三方后使用");
|
||||
}
|
||||
|
||||
var accessToken = await _accountManager.GetTokenByUserIdAsync(authEntity.UserId);
|
||||
return new { token= accessToken };
|
||||
return new { token = accessToken };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,6 +78,7 @@ namespace Yi.Framework.Rbac.Application.Services.Authentication
|
||||
{
|
||||
throw new UserFriendlyException("绑定失败,该第三方账号已被注册");
|
||||
}
|
||||
|
||||
var authAggregateRoot = new AuthAggregateRoot(scheme, userId ?? Guid.Empty, openId, name);
|
||||
|
||||
await _repository.InsertAsync(authAggregateRoot);
|
||||
@@ -84,6 +92,7 @@ namespace Yi.Framework.Rbac.Application.Services.Authentication
|
||||
{
|
||||
throw new UserFriendlyException(authenticateResult.Failure.Message);
|
||||
}
|
||||
|
||||
var openidClaim = authenticateResult.Principal.Claims.Where(x => x.Type == "urn:openid").FirstOrDefault();
|
||||
var nameClaim = authenticateResult.Principal.Claims.Where(x => x.Type == "urn:name").FirstOrDefault();
|
||||
return (openidClaim.Value, nameClaim.Value);
|
||||
@@ -104,21 +113,31 @@ namespace Yi.Framework.Rbac.Application.Services.Authentication
|
||||
return (await GetListAsync(input)).Items;
|
||||
}
|
||||
|
||||
public async Task<AuthOutputDto?> TryGetByOpenIdAsync(string openId, string authType)
|
||||
{
|
||||
var entity = await _repository._DbQueryable.Where(x => x.OpenId == openId)
|
||||
.Where(x => x.AuthType == authType)
|
||||
.FirstAsync();
|
||||
var output = await MapToGetOutputDtoAsync(entity);
|
||||
return output;
|
||||
}
|
||||
|
||||
public override async Task<PagedResultDto<AuthOutputDto>> GetListAsync(AuthGetListInput input)
|
||||
{
|
||||
RefAsync<int> total = 0;
|
||||
|
||||
var entities = await _repository._DbQueryable.WhereIF(input.UserId is not null, x => x.UserId == input.UserId)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.AuthType), x => x.AuthType == input.AuthType)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.OpenId), x => x.OpenId == input.OpenId)
|
||||
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
|
||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||
var entities = await _repository._DbQueryable
|
||||
.WhereIF(input.UserId is not null, x => x.UserId == input.UserId)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.AuthType), x => x.AuthType == input.AuthType)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.OpenId), x => x.OpenId == input.OpenId)
|
||||
.WhereIF(input.StartTime is not null && input.EndTime is not null,
|
||||
x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
|
||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||
return new PagedResultDto<AuthOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
|
||||
}
|
||||
|
||||
[RemoteService(IsEnabled = false)]
|
||||
public override Task<AuthOutputDto> UpdateAsync(Guid id, AuthOutputDto input)
|
||||
public override Task<AuthOutputDto> UpdateAsync(Guid id, AuthCreateOrUpdateInputDto input)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -135,9 +154,23 @@ namespace Yi.Framework.Rbac.Application.Services.Authentication
|
||||
}
|
||||
|
||||
[RemoteService(IsEnabled = false)]
|
||||
public override Task<AuthOutputDto> CreateAsync(AuthOutputDto input)
|
||||
public override async Task<AuthOutputDto> CreateAsync(AuthCreateOrUpdateInputDto input)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var entity = await MapToEntityAsync(input);
|
||||
await _repository.InsertAsync(entity);
|
||||
return MapToGetOutputDto(entity);
|
||||
}
|
||||
|
||||
protected override async Task CheckCreateInputDtoAsync(AuthCreateOrUpdateInputDto input)
|
||||
{
|
||||
//同一个类型,一个用户只能绑定一个第三方授权
|
||||
var isAny = await _repository._DbQueryable.Where(x => x.AuthType == input.AuthType)
|
||||
.Where(x => x.OpenId == input.OpenId || x.UserId == input.UserId).AnyAsync();
|
||||
|
||||
if (isAny)
|
||||
{
|
||||
throw new UserFriendlyException("该用户已有此应用授权");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user