diff --git a/WGShare.API/Controllers/AuthController.cs b/WGShare.API/Controllers/AuthController.cs index ea0c581..58b8cae 100644 --- a/WGShare.API/Controllers/AuthController.cs +++ b/WGShare.API/Controllers/AuthController.cs @@ -25,15 +25,18 @@ namespace WGShare.API.Controllers private readonly JwtHelper _jwtHelper; private readonly IConfiguration _configuration; private readonly IHubContext _hubContext; + private readonly ILogger _logger; public AuthController(ISqlSugarClient sqlSugar, JwtHelper jwtHelper, IConfiguration configuration, - IHubContext hubContext) + IHubContext hubContext, + ILogger logger) { _sqlSugar = sqlSugar; _jwtHelper = jwtHelper; this._configuration = configuration; this._hubContext = hubContext; + this._logger = logger; } /// @@ -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(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, diff --git a/WGShare.API/ServiceConfigs/AuthonizationFilter.cs b/WGShare.API/ServiceConfigs/AuthonizationFilter.cs index 15ea054..9459fe3 100644 --- a/WGShare.API/ServiceConfigs/AuthonizationFilter.cs +++ b/WGShare.API/ServiceConfigs/AuthonizationFilter.cs @@ -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(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; diff --git a/WGShare.API/WGShare.API.xml b/WGShare.API/WGShare.API.xml index 6e632e8..4706093 100644 --- a/WGShare.API/WGShare.API.xml +++ b/WGShare.API/WGShare.API.xml @@ -445,7 +445,7 @@ - + 强制退出 diff --git a/WGShare.Domain/DTOs/Login/AccessAndRefreshToken.cs b/WGShare.Domain/DTOs/Login/AccessAndRefreshToken.cs new file mode 100644 index 0000000..6c8baa5 --- /dev/null +++ b/WGShare.Domain/DTOs/Login/AccessAndRefreshToken.cs @@ -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; } + } +}