Merge pull request 'v2 优化TokenVersion机制' (#305) from Junong/Admin.NET.Pro:v2 into v2

Reviewed-on: https://code.adminnet.top/Admin.NET/Admin.NET.Pro/pulls/305
This commit is contained in:
zuohuaijun 2025-04-07 11:23:33 +08:00
commit 7f0fa0678d
3 changed files with 22 additions and 12 deletions

View File

@ -352,8 +352,8 @@ public class SysAuthService : IDynamicApiController, ITransient
// .Where(u => u.Id == _userManager.UserId) // .Where(u => u.Id == _userManager.UserId)
// .ExecuteCommandAsync(); // .ExecuteCommandAsync();
// 更新用户Token版本缓存 //// 更新用户Token版本缓存 退出系统不用更新系统缓存,更新后其他已登录机全都要重新登录。
_sysCacheService.Set($"{CacheConst.KeyUserToken}{_userManager.UserId}", $"{_userManager.TokenVersion + 1}"); //_sysCacheService.Set($"{CacheConst.KeyUserToken}{_userManager.UserId}", $"{_userManager.TokenVersion + 1}");
// 发布系统退出事件 // 发布系统退出事件
await _eventPublisher.PublishAsync(UserEventTypeEnum.Logout, _userManager); await _eventPublisher.PublishAsync(UserEventTypeEnum.Logout, _userManager);

View File

@ -140,7 +140,8 @@ public class SysUserService : IDynamicApiController, ITransient
if (await query.AnyAsync(u => u.Account == input.Account)) throw Oops.Oh(ErrorCodeEnum.D1003); if (await query.AnyAsync(u => u.Account == input.Account)) throw Oops.Oh(ErrorCodeEnum.D1003);
if (!string.IsNullOrWhiteSpace(input.Phone) && await query.AnyAsync(u => u.Phone == input.Phone)) throw Oops.Oh(ErrorCodeEnum.D1032); if (!string.IsNullOrWhiteSpace(input.Phone) && await query.AnyAsync(u => u.Phone == input.Phone)) throw Oops.Oh(ErrorCodeEnum.D1032);
input.TokenVersion++; ////更新用户普通信息时不因更新TokenVersion
//input.TokenVersion++;
var user = input.Adapt<SysUser>(); var user = input.Adapt<SysUser>();
await _sysUserRep.AsUpdateable(user).IgnoreColumns(true).IgnoreColumns(u => new { u.Password, u.Status, u.TenantId }).ExecuteCommandAsync(); await _sysUserRep.AsUpdateable(user).IgnoreColumns(true).IgnoreColumns(u => new { u.Password, u.Status, u.TenantId }).ExecuteCommandAsync();
@ -287,14 +288,17 @@ public class SysUserService : IDynamicApiController, ITransient
{ {
var user = await _sysUserRep.GetByIdAsync(input.UserId) ?? throw Oops.Oh(ErrorCodeEnum.D0009); var user = await _sysUserRep.GetByIdAsync(input.UserId) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
// 若账号的角色发生变化,才更新
var roles = await _sysUserRoleService.GetUserRoleIdList(input.UserId);
if(!roles.SequenceEqual(input.RoleIdList))
{
await _sysUserRoleService.GrantUserRole(input); await _sysUserRoleService.GrantUserRole(input);
// 强制下线账号和失效Token // 强制下线账号和失效Token
await OfflineAndExpireToken(user); await OfflineAndExpireToken(user);
// 发布更新用户角色事件 // 发布更新用户角色事件
await _eventPublisher.PublishAsync(UserEventTypeEnum.UpdateRole, input); await _eventPublisher.PublishAsync(UserEventTypeEnum.UpdateRole, input);
} }
}
/// <summary> /// <summary>
/// 修改用户密码 🔖 /// 修改用户密码 🔖
@ -461,8 +465,8 @@ public class SysUserService : IDynamicApiController, ITransient
/// <param name="user"></param> /// <param name="user"></param>
private async Task OfflineAndExpireToken(SysUser user) private async Task OfflineAndExpireToken(SysUser user)
{ {
// 更新Token版本缓存 // 更新Token版本缓存当角色、机构、密码、重置、删除、状态改变时Token版本清0
_sysCacheService.Set($"{CacheConst.KeyUserToken}{user.Id}", $"{user.TokenVersion + 1}"); _sysCacheService.Remove($"{CacheConst.KeyUserToken}{user.Id}");
// 强制下线账号 // 强制下线账号
await _sysOnlineUserService.ForceOfflineByUserId(user.Id); await _sysOnlineUserService.ForceOfflineByUserId(user.Id);

View File

@ -49,6 +49,12 @@ namespace Admin.NET.Web.Core
{ {
// 查库并缓存用户Token版本 // 查库并缓存用户Token版本
var user = await serviceScope.ServiceProvider.GetRequiredService<ISqlSugarClient>().Queryable<SysUser>().FirstAsync(u => u.Id == long.Parse(userId)); var user = await serviceScope.ServiceProvider.GetRequiredService<ISqlSugarClient>().Queryable<SysUser>().FirstAsync(u => u.Id == long.Parse(userId));
if (user == null || user.IsDelete)
{
context.Fail(new AuthorizationFailureReason(this, "账户失效或被禁止"));
context.GetCurrentHttpContext().SignoutToSwagger();
return;
}
sysCacheService.Set($"{CacheConst.KeyUserToken}{user.Id}", $"{user.TokenVersion}"); sysCacheService.Set($"{CacheConst.KeyUserToken}{user.Id}", $"{user.TokenVersion}");
tokenVersion2 = user.TokenVersion.ToString(); tokenVersion2 = user.TokenVersion.ToString();
} }