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

View File

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.SignalR;
using WGShare.API.Helpers; using WGShare.API.Helpers;
using WGShare.API.Hubs; using WGShare.API.Hubs;
using WGShare.Domain.Constant; using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Login;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
namespace WGShare.API.ServiceConfigs namespace WGShare.API.ServiceConfigs
@ -11,11 +12,9 @@ namespace WGShare.API.ServiceConfigs
{ {
public void OnAuthorization(AuthorizationFilterContext context) 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; var uid = context.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "uid")?.Value;
if (string.IsNullOrWhiteSpace(uid)) if (string.IsNullOrWhiteSpace(uid))
{ {
@ -23,15 +22,15 @@ namespace WGShare.API.ServiceConfigs
context.HttpContext.Response.StatusCode = 401; context.HttpContext.Response.StatusCode = 401;
return; return;
} }
var cacheToken = RedisHelper.Instance.Get(RedisKeyConstant.Data.GetAccessTokenKey(uid)); var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(uid));
if (string.IsNullOrWhiteSpace(cacheToken)) if (tokens == null)
{ {
context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult(new { message = "身份失效,请重新登录!" }); context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult(new { message = "身份失效,请重新登录!" });
context.HttpContext.Response.StatusCode = 401; context.HttpContext.Response.StatusCode = 401;
return; return;
} }
var token = context.HttpContext.Request.Headers.Authorization.FirstOrDefault().Replace("Bearer ", ""); 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.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult(new { message = "此账号已在别处登录,您被迫下线!" });
context.HttpContext.Response.StatusCode = 401; context.HttpContext.Response.StatusCode = 401;

View File

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