当前为单体架构 ,如果是分布式架构则需用分布式缓存
1.创建一个全局缓存,登录的时候写入
2.关闭jwt自带的时间校验 使用自定义的校验
(OnTokenValidated 更新最后一次操作时间
OnMessageReceived 判断是否过期,删除与否
)
public static ConcurrentDictionary<string, DateTime> _TokenManager = new ConcurrentDictionary<string, DateTime>();
public static void Configure(IServiceCollection services, IConfiguration configuration)
{
if (bool.Parse(configuration["Authentication:JwtBearer:IsEnabled"]))
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "JwtBearer";
options.DefaultChallengeScheme = "JwtBearer";
}).AddJwtBearer("JwtBearer", options =>
{
options.Audience = configuration["Authentication:JwtBearer:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(configuration["Authentication:JwtBearer:SecurityKey"])),
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = configuration["Authentication:JwtBearer:Issuer"],
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = configuration["Authentication:JwtBearer:Audience"],
Validate the token expiry
ValidateLifetime = false,
// If you want to allow a certain amount of clock drift, set that here
ClockSkew = TimeSpan.Zero
};
options.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var _TokenManager = TokenAuthController._TokenManager;
var requestToken = getToken(context.HttpContext.Request); //context.HttpContext.Request.Headers.Where(c => c.Key == "Authorization").FirstOrDefault().Value.ToString() ?? "";
_TokenManager[requestToken] = DateTime.Now;
return Task.CompletedTask;
},
OnMessageReceived = context =>
{
if (!context.HttpContext.Request.Headers.Any(c => c.Key == "Authorization"))
return Task.CompletedTask;
var _TokenManager = TokenAuthController._TokenManager;
var requestToken = getToken(context.HttpContext.Request);// context.HttpContext.Request.Headers.Where(c => c.Key == "Authorization").FirstOrDefault().Value.ToString() ?? "";
if (!_TokenManager.Where(c => c.Key == requestToken).Any())
{
context.Response.Headers.Add("Access-Control-Expose-Headers", "Token-Expired");
context.Response.Headers.Add("Token-Expired", "true");
context.Fail(new Exception("Token有效期已过,已删除"));
return Task.CompletedTask;
}
var currToken = _TokenManager.Where(c => c.Key == requestToken).FirstOrDefault();
//距离最后一次操作间隔时长
var timeSpan = GetTimeSpan(DateTime.Now, currToken.Value);
//Token expired
if ((timeSpan > 1))
{
context.Response.Headers.Add("Access-Control-Expose-Headers", "Token-Expired");
context.Response.Headers.Add("Token-Expired", "true");
_TokenManager.TryRemove(currToken);
context.Fail(new Exception("Token过期"));
//清空废弃的数据
var removeItems = _TokenManager.Where(c => GetTimeSpan(DateTime.Now, c.Value) > 60).ToList();
foreach (var item in removeItems)
_TokenManager.TryRemove(item);
}
return Task.CompletedTask;
},
};
});
}
}
private static string getToken(HttpRequest Request1)
{
var requestToken = Request1.Headers.Where(c => c.Key == "Authorization").FirstOrDefault().Value.ToString() ?? "";
var t = requestToken.Replace("Bearer ", "").Replace("bearer ", "");
return t;
}