别处登录,删除刷新token

This commit is contained in:
youngq 2024-08-13 18:24:12 +08:00
parent 03358fc745
commit e7ea6956ef
4 changed files with 55 additions and 26 deletions

View File

@ -25,15 +25,18 @@ namespace WGShare.API.Controllers
private readonly JwtHelper _jwtHelper;
private readonly IConfiguration _configuration;
private readonly IHubContext<SessionManageHub, IMessageClient> _hubContext;
private readonly ILogger<AuthController> _logger;
public AuthController(ISqlSugarClient sqlSugar, JwtHelper jwtHelper,
IConfiguration configuration,
IHubContext<SessionManageHub, IMessageClient> hubContext)
IHubContext<SessionManageHub, IMessageClient> hubContext,
ILogger<AuthController> logger)
{
_sqlSugar = sqlSugar;
_jwtHelper = jwtHelper;
this._configuration = configuration;
this._hubContext = hubContext;
this._logger = logger;
}
/// <summary>
@ -89,27 +92,36 @@ namespace WGShare.API.Controllers
btnAutn.Add(new Claim("uname", user.UserName));
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
// 获取已登录的token
var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(user.Id));
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
var refreshToken = Guid.NewGuid().ToString();
using (var pipe = RedisHelper.Instance.StartPipe())
{
if (tokens != null)
{
// 删除刷新token
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(tokens.RefreshToken));
}
// 设置新的刷新token
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
// 记录accessToken
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
{
AccessToken = accessToken,
RefreshToken = refreshToken
}, _configuration["Jwt:Expires"].ToInt32());
pipe.EndPipe();
}
// 强制下线
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(user.TenantId), user.Id);
if (!string.IsNullOrWhiteSpace(connectId))
{
_logger.LogInformation($"账号已在其他地方登录强制下线account:{user.Account} connectId:{connectId}");
await _hubContext.Clients.Client(connectId).ForceLogout("账号已在其他地方登录,您被迫下线!");
}
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
var refreshToken = Guid.NewGuid().ToString();
using (var pipe = RedisHelper.Instance.StartPipe())
{
// 设置刷新token
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
// 记录accessToken
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), accessToken, _configuration["Jwt:Expires"].ToInt32());
pipe.EndPipe();
}
return Ok(new
{
perms = user.PermValue,
@ -153,7 +165,11 @@ namespace WGShare.API.Controllers
{
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), accessToken, _configuration["Jwt:Expires"].ToInt32());
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
{
AccessToken = accessToken,
RefreshToken = refreshTokenNew
}, _configuration["Jwt:Expires"].ToInt32());
pipe.EndPipe();
}
@ -161,7 +177,7 @@ namespace WGShare.API.Controllers
return Ok(new
{
perms = user.PermValue,
token = _jwtHelper.CreateToken(user.Id, btnAutn),
token = accessToken,
refresh_token = refreshTokenNew,
roleId = user.RoleId,
userName = user.UserName,

View File

@ -3,19 +3,18 @@ using Microsoft.AspNetCore.SignalR;
using WGShare.API.Helpers;
using WGShare.API.Hubs;
using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Login;
using WGShare.Domain.Entities;
namespace WGShare.API.ServiceConfigs
{
public class AuthonizationFilter : Attribute, IAuthorizationFilter
{
{
public void OnAuthorization(AuthorizationFilterContext context)
{
//Console.WriteLine("验证结果:" + context.HttpContext.User.Identity.IsAuthenticated);
if (context.HttpContext.User.Identity.IsAuthenticated)
if (context.HttpContext.User.Identity.IsAuthenticated
&& !context.HttpContext.GetEndpoint().Metadata.Any(x => x is Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute))
{
//context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult(new { message = "请先登录" });
var uid = context.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "uid")?.Value;
if (string.IsNullOrWhiteSpace(uid))
{
@ -23,16 +22,16 @@ namespace WGShare.API.ServiceConfigs
context.HttpContext.Response.StatusCode = 401;
return;
}
var cacheToken = RedisHelper.Instance.Get(RedisKeyConstant.Data.GetAccessTokenKey(uid));
if (string.IsNullOrWhiteSpace(cacheToken))
var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(uid));
if (tokens == null)
{
context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult(new { message = "身份失效,请重新登录!" });
context.HttpContext.Response.StatusCode = 401;
return;
}
var token = context.HttpContext.Request.Headers.Authorization.FirstOrDefault().Replace("Bearer ", "");
if (token != cacheToken)
{
if (token != tokens.AccessToken)
{
context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult(new { message = "此账号已在别处登录,您被迫下线!" });
context.HttpContext.Response.StatusCode = 401;
return;

View File

@ -445,7 +445,7 @@
<param name="user"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.ForceLogout">
<member name="M:WGShare.API.Hubs.IMessageClient.ForceLogout(System.String)">
<summary>
强制退出
</summary>

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.Login
{
public class AccessAndRefreshToken
{
public string AccessToken { get; set; }
public string RefreshToken { get; set; }
}
}