我想跟踪用户上次在我们网站上活跃的时间。
一种方法是编写中间件,用每个经过身份验证的页面请求更新数据库。然而,我有点担心这种技术的开销。
我更愿意只跟踪他们上次登录的时间。例如,如果他们保持登录状态 30 天,那么对于我们的目的来说,了解他们在该时间范围内登录就足够准确了。
但是,ASP.NET Core Identity 似乎可能使用滑动窗口,其中 30 天计数器在每次访问页面时都会重置。
有没有什么方法可以粗略地了解他们上次在网站上活动的时间,而不必每次页面请求都更新数据库?
注意: 在 ASP.NET 的早期版本中,我们似乎有会话事件(启动等)。如果不需要在每个页面请求上更新数据库,似乎这样的东西是理想的。
您可以使用
LastActivityTime
和中间件来更新用户的上次活动时间,前提是自上次记录的活动以来已经过去了一定的时间。这将减少数据库负载。您可以使用内存缓存来存储上次活动时间。
启动.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddControllersWithViews();
.........
.......
}
中间件:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Threading.Tasks;
public class ActivityTrackingMiddleware
{
private readonly RequestDelegate _next;
public ActivityTrackingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, UserManager<ApplicationUser> userManager, IMemoryCache cache)
{
var user = context.User;
if (user.Identity.IsAuthenticated)
{
var userId = userManager.GetUserId(user);
var cacheKey = $"LastActivityTime_{userId}";
var lastActivity = cache.Get<DateTime>(cacheKey);
if (lastActivity == default || DateTime.UtcNow - lastActivity > TimeSpan.FromHours(1))
{
var appUser = await userManager.FindByIdAsync(userId);
if (appUser != null)
{
appUser.LastActivityTime = DateTime.UtcNow;
await userManager.UpdateAsync(appUser);
cache.Set(cacheKey, appUser.LastActivityTime, TimeSpan.FromDays(1));
}
}
}
await _next(context);
}
}
不要忘记在 Startup.cs 文件中注册中间件:
app.UseMiddleware<ActivityTrackingMiddleware>();