fix(auth): 修复JWT令牌登出和刷新中间件问题
- 调整登出流程,先将JWT令牌加入黑名单再删除Cookie - 在HttpHelper中添加空响应检查,防止接口返回空内容时出错 - 在配额监控服务中增加底层白名单检查的日志记录 - 优化刷新令牌中间件,跳过登录相关页面和静态资源的令牌检查 - 改进令牌失效响应,设置正确的Content-Type并提供多语言提示信息
This commit is contained in:
@@ -76,6 +76,13 @@ namespace YLErp.Helpers
|
||||
// 发送请求并响应结果
|
||||
var response = await client.ExecuteAsync<ReponseWrap<TResponse>>(request);
|
||||
var responseContent = response.Content;
|
||||
|
||||
// 检查响应内容是否为空
|
||||
if (string.IsNullOrEmpty(responseContent))
|
||||
{
|
||||
throw new ServiceException($"接口返回为空 - URL: {_baseUrl}{apiPath}, StatusCode: {response.StatusCode}");
|
||||
}
|
||||
|
||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<TResponse>(responseContent);
|
||||
}
|
||||
public async Task<TResponse> GetRequestNoAuth<TResponse>(string apiPath)
|
||||
|
||||
@@ -4970,6 +4970,7 @@ namespace YLErp.Modules.RiskModule
|
||||
foreach (var item in positions)
|
||||
{
|
||||
CheckUnderlyingRequest clientOrderParam = new CheckUnderlyingRequest() { clientId = clientId, securityId = item.UnderlyingCode, orderQty = item.PosiQuantity * 0.0001m, side = item.PositionType - 1 };
|
||||
_logger.Info($"[CheckUnderlyingWhiteList] 构建请求参数 - clientId: {clientId}, securityId: {item.UnderlyingCode}, orderQty: {item.PosiQuantity * 0.0001m}, side: {item.PositionType - 1}");
|
||||
clientOrderParams.Add(clientOrderParam);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(baseUrl) && !string.IsNullOrEmpty(checkUrl))
|
||||
|
||||
@@ -311,13 +311,9 @@ namespace YLErp.Web.Controllers
|
||||
HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
|
||||
logger.Info($"[退出登录] SignOutAsync 已调用");
|
||||
|
||||
// 清除 JWT Token Cookie
|
||||
Response.Cookies.Delete("Access-Token");
|
||||
Response.Cookies.Delete("Access-Token-Encrypt");
|
||||
logger.Info($"[退出登录] JWT Token Cookie 已清除");
|
||||
|
||||
// 将当前 JWT Token 加入黑名单(使其立即失效)
|
||||
if (Request.Cookies.TryGetValue("Access-Token", out var accessToken) && !string.IsNullOrEmpty(accessToken))
|
||||
// 先将当前 JWT Token 加入黑名单(使其立即失效),然后再删除 Cookie
|
||||
string accessToken = null;
|
||||
if (Request.Cookies.TryGetValue("Access-Token", out accessToken) && !string.IsNullOrEmpty(accessToken))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -340,6 +336,11 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
// 清除 JWT Token Cookie(在加入黑名单之后)
|
||||
Response.Cookies.Delete("Access-Token");
|
||||
Response.Cookies.Delete("Access-Token-Encrypt");
|
||||
logger.Info($"[退出登录] JWT Token Cookie 已清除");
|
||||
|
||||
if (SsoLoginConfig.SSO_Enable)
|
||||
{
|
||||
switch (loginName?.ToLowerInvariant())
|
||||
|
||||
@@ -34,6 +34,25 @@ namespace YLErp.Web.Middleware
|
||||
/// <param name="context">HTTP上下文</param>
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
// 获取当前请求路径
|
||||
var path = context.Request.Path.Value?.ToLowerInvariant() ?? "";
|
||||
|
||||
// 跳过登录相关页面和静态资源,避免黑名单Token影响登录流程
|
||||
if (path.StartsWith("/account/login") ||
|
||||
path.StartsWith("/account/logout") ||
|
||||
path.StartsWith("/account/captcha") ||
|
||||
path.StartsWith("/account/sso") ||
|
||||
path.StartsWith("/account/callback") ||
|
||||
path.StartsWith("/content/") ||
|
||||
path.StartsWith("/scripts/") ||
|
||||
path.StartsWith("/css/") ||
|
||||
path.StartsWith("/images/") ||
|
||||
path.StartsWith("/favicon.ico"))
|
||||
{
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否有Access-Token
|
||||
if (context.Request.Cookies.TryGetValue("Access-Token", out var token))
|
||||
{
|
||||
@@ -66,7 +85,8 @@ namespace YLErp.Web.Middleware
|
||||
context.Response.Cookies.Delete("Access-Token");
|
||||
context.Response.Cookies.Delete("Access-Token-Encrypt");
|
||||
context.Response.StatusCode = 401;
|
||||
await context.Response.WriteAsync("Token已失效,请重新登录");
|
||||
context.Response.ContentType = "text/plain; charset=utf-8";
|
||||
await context.Response.WriteAsync("Token has expired / Token已失效,请重新登录 (Please go to login page / 请访问登录页面: /Account/Login)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user