feat: 新增用户信息缓存管理
This commit is contained in:
@@ -3,6 +3,7 @@ using Lazy.Captcha.Core;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Caching.Distributed;
|
using Microsoft.Extensions.Caching.Distributed;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
@@ -33,15 +34,17 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
private readonly IGuidGenerator _guidGenerator;
|
private readonly IGuidGenerator _guidGenerator;
|
||||||
private readonly RbacOptions _rbacOptions;
|
private readonly RbacOptions _rbacOptions;
|
||||||
private readonly IAliyunManger _aliyunManger;
|
private readonly IAliyunManger _aliyunManger;
|
||||||
|
private IDistributedCache<UserInfoCacheItem, UserInfoCacheKey> _userCache;
|
||||||
public AccountService(IUserRepository userRepository,
|
public AccountService(IUserRepository userRepository,
|
||||||
ICurrentUser currentUser,
|
ICurrentUser currentUser,
|
||||||
IAccountManager accountManager,
|
IAccountManager accountManager,
|
||||||
ISqlSugarRepository<MenuEntity> menuRepository,
|
ISqlSugarRepository<MenuEntity> menuRepository,
|
||||||
IDistributedCache<CaptchaPhoneCacheItem, CaptchaPhoneCacheKey> phoneCache,
|
IDistributedCache<CaptchaPhoneCacheItem, CaptchaPhoneCacheKey> phoneCache,
|
||||||
|
IDistributedCache<UserInfoCacheItem, UserInfoCacheKey> userCache,
|
||||||
ICaptcha captcha,
|
ICaptcha captcha,
|
||||||
IGuidGenerator guidGenerator,
|
IGuidGenerator guidGenerator,
|
||||||
IOptions<RbacOptions> options,
|
IOptions<RbacOptions> options,
|
||||||
IAliyunManger aliyunManger )
|
IAliyunManger aliyunManger)
|
||||||
{
|
{
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_currentUser = currentUser;
|
_currentUser = currentUser;
|
||||||
@@ -52,6 +55,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
_guidGenerator = guidGenerator;
|
_guidGenerator = guidGenerator;
|
||||||
_rbacOptions = options.Value;
|
_rbacOptions = options.Value;
|
||||||
_aliyunManger = aliyunManger;
|
_aliyunManger = aliyunManger;
|
||||||
|
_userCache = userCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,10 +117,10 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
[Authorize(AuthenticationSchemes = TokenTypeConst.Refresh)]
|
[Authorize(AuthenticationSchemes = TokenTypeConst.Refresh)]
|
||||||
public async Task<object> PostRefreshAsync([FromQuery] string refresh_token)
|
public async Task<object> PostRefreshAsync([FromQuery] string refresh_token)
|
||||||
{
|
{
|
||||||
var userId = CurrentUser.Id.Value;
|
var userId = CurrentUser.Id.Value;
|
||||||
var accessToken = await _accountManager.GetTokenByUserIdAsync(userId);
|
var accessToken = await _accountManager.GetTokenByUserIdAsync(userId);
|
||||||
var refreshToken = _accountManager.CreateRefreshToken(userId);
|
var refreshToken = _accountManager.CreateRefreshToken(userId);
|
||||||
return new { Token = accessToken, RefreshToken = refreshToken };
|
return new { Token = accessToken, RefreshToken = refreshToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -249,7 +253,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询已登录的账户信息
|
/// 查询已登录的账户信息,已缓存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Route("account")]
|
[Route("account")]
|
||||||
@@ -263,16 +267,33 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
{
|
{
|
||||||
throw new UserFriendlyException("用户未登录");
|
throw new UserFriendlyException("用户未登录");
|
||||||
}
|
}
|
||||||
//此处从缓存中获取也行
|
//此处优先从缓存中获取
|
||||||
//var data = _cacheManager.Get<UserRoleMenuDto>($"Yi:UserInfo:{userId}");
|
UserRoleMenuDto output = null;
|
||||||
var data = await _userRepository.GetUserAllInfoAsync(userId ?? Guid.Empty);
|
var cacheData = await _userCache.GetAsync(new UserInfoCacheKey(userId.Value));
|
||||||
//系统用户数据被重置,老前端访问重新授权
|
if (cacheData is not null)
|
||||||
if (data is null)
|
|
||||||
{
|
{
|
||||||
throw new AbpAuthorizationException();
|
output = cacheData.Info;
|
||||||
}
|
}
|
||||||
data.Menus.Clear();
|
else
|
||||||
return data;
|
{
|
||||||
|
var data = await _userRepository.GetUserAllInfoAsync(userId.Value);
|
||||||
|
//系统用户数据被重置,老前端访问重新授权
|
||||||
|
if (data is null)
|
||||||
|
{
|
||||||
|
throw new AbpAuthorizationException();
|
||||||
|
}
|
||||||
|
data.Menus.Clear();
|
||||||
|
|
||||||
|
output = data;
|
||||||
|
|
||||||
|
var tokenExpiresMinuteTime = LazyServiceProvider.GetRequiredService<IOptions<JwtOptions>>().Value.ExpiresMinuteTime;
|
||||||
|
//将用户信息放入缓存,下次获取直接从缓存中获取即可,过期时间为token过期时间
|
||||||
|
await _userCache.SetAsync(new UserInfoCacheKey(userId.Value), new UserInfoCacheItem(data), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(tokenExpiresMinuteTime) });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -307,10 +328,18 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
/// 退出登录
|
/// 退出登录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task<bool> PostLogout()
|
public async Task<bool> PostLogout()
|
||||||
{
|
{
|
||||||
|
//通过鉴权jwt获取到用户的id
|
||||||
|
var userId = _currentUser.Id;
|
||||||
|
if (userId is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
// throw new UserFriendlyException("用户已退出");
|
||||||
|
}
|
||||||
|
await _userCache.RemoveAsync(new UserInfoCacheKey(userId.Value));
|
||||||
//Jwt去中心化登出,只需用记录日志即可
|
//Jwt去中心化登出,只需用记录日志即可
|
||||||
return Task.FromResult(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.Rbac.Domain.Shared.Dtos;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Rbac.Domain.Shared.Caches
|
||||||
|
{
|
||||||
|
public class UserInfoCacheItem
|
||||||
|
{
|
||||||
|
public UserInfoCacheItem(UserRoleMenuDto info) { Info = info; }
|
||||||
|
/// <summary>
|
||||||
|
/// 存储的用户信息
|
||||||
|
/// </summary>
|
||||||
|
public UserRoleMenuDto Info { get; set; }
|
||||||
|
}
|
||||||
|
public class UserInfoCacheKey
|
||||||
|
{
|
||||||
|
public UserInfoCacheKey(Guid userId) { UserId = userId; }
|
||||||
|
|
||||||
|
public Guid UserId { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Yi:User:{UserId}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,15 +6,15 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Volo.Abp;
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.Domain.Entities;
|
using Volo.Abp.Domain.Entities;
|
||||||
using Volo.Abp.Domain.Services;
|
using Volo.Abp.Domain.Services;
|
||||||
using Volo.Abp.EventBus.Local;
|
using Volo.Abp.EventBus.Local;
|
||||||
using Volo.Abp.Security.Claims;
|
using Volo.Abp.Security.Claims;
|
||||||
using Volo.Abp.Users;
|
|
||||||
using Yi.Framework.Core.Helper;
|
using Yi.Framework.Core.Helper;
|
||||||
using Yi.Framework.Rbac.Domain.Entities;
|
using Yi.Framework.Rbac.Domain.Entities;
|
||||||
using Yi.Framework.Rbac.Domain.Repositories;
|
using Yi.Framework.Rbac.Domain.Repositories;
|
||||||
|
using Yi.Framework.Rbac.Domain.Shared.Caches;
|
||||||
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
||||||
using Yi.Framework.Rbac.Domain.Shared.Dtos;
|
using Yi.Framework.Rbac.Domain.Shared.Dtos;
|
||||||
using Yi.Framework.Rbac.Domain.Shared.Etos;
|
using Yi.Framework.Rbac.Domain.Shared.Etos;
|
||||||
@@ -38,6 +38,7 @@ namespace Yi.Framework.Rbac.Domain.Managers
|
|||||||
private UserManager _userManager;
|
private UserManager _userManager;
|
||||||
private ISqlSugarRepository<RoleEntity> _roleRepository;
|
private ISqlSugarRepository<RoleEntity> _roleRepository;
|
||||||
private RefreshJwtOptions _refreshJwtOptions;
|
private RefreshJwtOptions _refreshJwtOptions;
|
||||||
|
|
||||||
public AccountManager(IUserRepository repository
|
public AccountManager(IUserRepository repository
|
||||||
, IHttpContextAccessor httpContextAccessor
|
, IHttpContextAccessor httpContextAccessor
|
||||||
, IOptions<JwtOptions> jwtOptions
|
, IOptions<JwtOptions> jwtOptions
|
||||||
@@ -87,9 +88,9 @@ namespace Yi.Framework.Rbac.Domain.Managers
|
|||||||
loginEto.UserId = userInfo.User.Id;
|
loginEto.UserId = userInfo.User.Id;
|
||||||
await _localEventBus.PublishAsync(loginEto);
|
await _localEventBus.PublishAsync(loginEto);
|
||||||
}
|
}
|
||||||
|
var accessToken = CreateToken(this.UserInfoToClaim(userInfo));
|
||||||
//将用户信息添加到缓存中,需要考虑的是更改了用户、角色、菜单等整个体系都需要将缓存进行刷新,看具体业务进行选择
|
//将用户信息添加到缓存中,需要考虑的是更改了用户、角色、菜单等整个体系都需要将缓存进行刷新,看具体业务进行选择
|
||||||
|
|
||||||
var accessToken = CreateToken(this.UserInfoToClaim(userInfo));
|
|
||||||
|
|
||||||
return accessToken;
|
return accessToken;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user