开启单设备登陆情况下,单用户可以在PC、APP端同时登陆连接signlar,不被强制下线并可以接收消息
This commit is contained in:
parent
97043f00fd
commit
4368c5510f
@ -99,7 +99,7 @@ public class AppAuthService : IDynamicApiController, ITransient
|
||||
// 登录成功则清空密码错误次数
|
||||
_sysCacheService.Remove(keyPasswordErrorTimes);
|
||||
|
||||
return await CreateToken(user);
|
||||
return await CreateToken(user, input.LoginMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -148,19 +148,23 @@ public class AppAuthService : IDynamicApiController, ITransient
|
||||
var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter().FirstAsync(u => u.Phone.Equals(input.Phone));
|
||||
_ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
|
||||
return await CreateToken(user);
|
||||
return await CreateToken(user, input.LoginMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成Token令牌 🔖
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="loginMode"></param>
|
||||
/// <returns></returns>
|
||||
[NonAction]
|
||||
public virtual async Task<LoginOutput> CreateToken(SysUser user)
|
||||
public virtual async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode)
|
||||
{
|
||||
// 兼容处理前端未传递loginMode,导致收不到消息
|
||||
if (loginMode == 0) loginMode = LoginModeEnum.PC;
|
||||
|
||||
// 单用户登录
|
||||
await _sysOnlineUserService.SingleLogin(user.Id);
|
||||
await _sysOnlineUserService.SingleLogin(user.Id, loginMode);
|
||||
|
||||
// 生成Token令牌
|
||||
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
||||
@ -174,6 +178,7 @@ public class AppAuthService : IDynamicApiController, ITransient
|
||||
{ AppClaimConst.OrgId, user.OrgId },
|
||||
{ AppClaimConst.OrgName, user.SysOrg?.Name },
|
||||
{ AppClaimConst.OrgType, user.SysOrg?.Type },
|
||||
{ ClaimConst.LoginMode, loginMode },
|
||||
}, tokenExpire);
|
||||
|
||||
// 生成刷新Token令牌
|
||||
|
||||
@ -65,4 +65,10 @@ public partial class SysOnlineUser : EntityTenantId
|
||||
[SugarColumn(ColumnDescription = "操作系统", Length = 128)]
|
||||
[MaxLength(128)]
|
||||
public string? Os { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登陆模式
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "登陆模式")]
|
||||
public LoginModeEnum LoginMode { get; set; }
|
||||
}
|
||||
@ -47,6 +47,7 @@ public class OnlineUserHub : Hub<IOnlineUserHub>
|
||||
var account = httpContext.User.FindFirst(ClaimConst.Account)?.Value;
|
||||
var realName = httpContext.User.FindFirst(ClaimConst.RealName)?.Value;
|
||||
var tenantId = (httpContext.User.FindFirst(ClaimConst.TenantId)?.Value).ToLong();
|
||||
var loginMode = (LoginModeEnum)(httpContext.User.FindFirst(ClaimConst.LoginMode)?.Value).ToInt();
|
||||
|
||||
var user = new SysOnlineUser
|
||||
{
|
||||
@ -59,13 +60,14 @@ public class OnlineUserHub : Hub<IOnlineUserHub>
|
||||
Browser = httpContext.GetClientBrowser(),
|
||||
Os = httpContext.GetClientOs(),
|
||||
TenantId = tenantId,
|
||||
LoginMode = loginMode,
|
||||
};
|
||||
await _sysOnlineUerRep.InsertAsync(user);
|
||||
|
||||
// 是否开启单用户登录
|
||||
if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin))
|
||||
{
|
||||
_sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId, user);
|
||||
_sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId + loginMode, user);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -34,6 +34,11 @@ public class LoginInput
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登陆模式
|
||||
/// </summary>
|
||||
public LoginModeEnum LoginMode { get; set; }
|
||||
}
|
||||
|
||||
public class LoginPhoneInput
|
||||
@ -52,4 +57,9 @@ public class LoginPhoneInput
|
||||
/// <example>123456</example>
|
||||
[Required(ErrorMessage = "验证码不能为空"), MinLength(4, ErrorMessage = "验证码不能少于4个字符")]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登陆模式
|
||||
/// </summary>
|
||||
public LoginModeEnum LoginMode { get; set; }
|
||||
}
|
||||
@ -123,7 +123,7 @@ public class SysAuthService : IDynamicApiController, ITransient
|
||||
// 登录成功则清空密码错误次数
|
||||
_sysCacheService.Remove(keyPasswordErrorTimes);
|
||||
|
||||
return await CreateToken(user);
|
||||
return await CreateToken(user, input.LoginMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -202,19 +202,23 @@ public class SysAuthService : IDynamicApiController, ITransient
|
||||
var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter().FirstAsync(u => u.Phone.Equals(input.Phone));
|
||||
_ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
|
||||
return await CreateToken(user);
|
||||
return await CreateToken(user, input.LoginMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成Token令牌 🔖
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="loginMode"></param>
|
||||
/// <returns></returns>
|
||||
[NonAction]
|
||||
internal async Task<LoginOutput> CreateToken(SysUser user)
|
||||
internal async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode)
|
||||
{
|
||||
// 兼容处理前端未传递loginMode,导致收不到消息
|
||||
if (loginMode == 0) loginMode = LoginModeEnum.PC;
|
||||
|
||||
// 单用户登录
|
||||
await _sysOnlineUserService.SingleLogin(user.Id);
|
||||
await _sysOnlineUserService.SingleLogin(user.Id, loginMode);
|
||||
|
||||
// 生成Token令牌
|
||||
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
||||
@ -228,6 +232,7 @@ public class SysAuthService : IDynamicApiController, ITransient
|
||||
{ ClaimConst.OrgId, user.OrgId },
|
||||
{ ClaimConst.OrgName, user.SysOrg?.Name },
|
||||
{ ClaimConst.OrgType, user.SysOrg?.Type },
|
||||
{ ClaimConst.LoginMode, loginMode },
|
||||
}, tokenExpire);
|
||||
|
||||
// 生成刷新Token令牌
|
||||
|
||||
@ -50,9 +50,14 @@ public class SysMessageService : IDynamicApiController, ITransient
|
||||
// 是否开启单用户登录
|
||||
if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin))
|
||||
{
|
||||
var user = _sysCacheService.Get<SysOnlineUser>(cacheKey);
|
||||
if (user == null) return;
|
||||
await _chatHubContext.Clients.AllExcept(user.ConnectionId).ReceiveMessage(input);
|
||||
var values = Enum.GetValues(typeof(LoginModeEnum)).Cast<LoginModeEnum>().ToList();
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
var user = _sysCacheService.Get<SysOnlineUser>(cacheKey + value);
|
||||
if (user == null) continue;
|
||||
await _chatHubContext.Clients.AllExcept(user.ConnectionId).ReceiveMessage(input);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -78,9 +83,14 @@ public class SysMessageService : IDynamicApiController, ITransient
|
||||
// 是否开启单用户登录
|
||||
if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin))
|
||||
{
|
||||
var user = _sysCacheService.Get<SysOnlineUser>(cacheKey);
|
||||
if (user == null) return;
|
||||
await _chatHubContext.Clients.Client(user.ConnectionId).ReceiveMessage(input);
|
||||
var values = Enum.GetValues(typeof(LoginModeEnum)).Cast<LoginModeEnum>().ToList();
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
var user = _sysCacheService.Get<SysOnlineUser>(cacheKey + value);
|
||||
if (user == null) continue;
|
||||
await _chatHubContext.Clients.Client(user.ConnectionId).ReceiveMessage(input);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -109,8 +119,13 @@ public class SysMessageService : IDynamicApiController, ITransient
|
||||
// 是否开启单用户登录
|
||||
if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin))
|
||||
{
|
||||
var user = _sysCacheService.Get<SysOnlineUser>(cacheKey);
|
||||
if (user != null) userList.Add(user.ConnectionId);
|
||||
var values = Enum.GetValues(typeof(LoginModeEnum)).Cast<LoginModeEnum>().ToList();
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
var user = _sysCacheService.Get<SysOnlineUser>(cacheKey + value);
|
||||
if (user != null) userList.Add(user.ConnectionId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -109,8 +109,8 @@ public class SysOAuthService : IDynamicApiController, ITransient
|
||||
wechatUser = await _sysOAuthUserRep.AsQueryable().Includes(u => u.SysUser).ClearFilter().FirstAsync(u => u.OpenId == openIdClaim.Value);
|
||||
}
|
||||
|
||||
// 构建Token令牌
|
||||
var token = await App.GetRequiredService<SysAuthService>().CreateToken(wechatUser.SysUser);
|
||||
// 构建Token令牌 TODO 这里先默认所有回调登陆的都是PC
|
||||
var token = await App.GetRequiredService<SysAuthService>().CreateToken(wechatUser.SysUser, LoginModeEnum.PC);
|
||||
|
||||
return new RedirectResult($"{redirectUrl}/#/login?token={token.AccessToken}");
|
||||
}
|
||||
|
||||
@ -74,16 +74,21 @@ public class SysOnlineUserService : IDynamicApiController, ITransient
|
||||
/// <summary>
|
||||
/// 单用户登录
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="loginMode"></param>
|
||||
/// <returns></returns>
|
||||
[NonAction]
|
||||
public async Task SingleLogin(long userId)
|
||||
public async Task SingleLogin(long userId, LoginModeEnum loginMode)
|
||||
{
|
||||
if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin))
|
||||
{
|
||||
var users = await _sysOnlineUerRep.GetListAsync(u => u.UserId == userId);
|
||||
foreach (var user in users)
|
||||
{
|
||||
await ForceOffline(user);
|
||||
if (loginMode == user.LoginMode)
|
||||
{
|
||||
await ForceOffline(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user