如何在asp.net core中处理cookie过期问题

7

我想了解如何正确处理cookie过期的情况?是否可以执行自定义操作?

我的目标是在cookie过期时,从当前cookie中提取一些信息,并将其重定向到由此信息参数化的操作。这是可能的吗?

3个回答

5

没有一个好的方法可以完成这个任务。如果cookie过期了,它不会被发送到服务器来提取任何信息。在ASP.Net Core Identity中,您对此没有太多控制权。这使得您只能使用Cookie Middleware。

当cookie过期时,这提供了一个普通的重定向给用户:

public void ConfigureServices(IServiceCollection services)
{       
    services.Configure<CookieAuthenticationOptions>(options =>
    {
        options.LoginPath = new PathString("/Home/Index");
    });
}

实现您需要的最佳方式是将cookie的过期时间设置得比真实用户会话过期时间晚得多,然后在服务器端执行会话过期并重定向用户。尽管这不是理想的方式,但当cookie过期时,您没有其他选择。

public void ConfigureServices(IServiceCollection services)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        AuthenticationScheme = "MyCookieMiddlewareInstance",
        // Redirect when cookie expired or not present
        LoginPath = new PathString("/Account/Unauthorized/"),
        AutomaticAuthenticate = true,
        // never expire cookie
        ExpireTimeSpan = TimeSpan.MaxValue,
        Events = new CookieAuthenticationEvents()
        {
            // in custom function set the session expiration
            // via the DB and reset it everytime this is called
            // if the session is still active
            // otherwise, you can redirect if it's invalid
            OnValidatePrincipal = <custom function here>
        }
    });
}

3

看起来您需要在设置cookie身份验证中间件时为OnValidatePrincipal事件编写自己的处理程序:

OnValidatePrincipal事件可以用于拦截和覆盖cookie身份验证的验证

app.UseCookieAuthentication(options =>
{
    options.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = <your event handler>
    };
});

ASP.NET文档包含这样一个处理程序的示例:

public static class LastChangedValidator
{
    public static async Task ValidateAsync(CookieValidatePrincipalContext context)
    {
        // Pull database from registered DI services.
        var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
        var userPrincipal = context.Principal;

        // Look for the last changed claim.
        string lastChanged;
        lastChanged = (from c in userPrincipal.Claims
                       where c.Type == "LastUpdated"
                       select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
        {
            context.RejectPrincipal();
            await context.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
        }
    }
}

14
如果 cookie 过期了,在 OnValidatePrincipal 方法中就不会出现它。 - adem caglin

2

看起来您的情况没有对应的事件,但您可以使用OnRedirectToLogin来更改重定向URI。这里是一个示例:

OnRedirectToLogin = async (context) =>
{
      var binding = context.HttpContext.Features.Get<ITlsTokenBindingFeature>()?.GetProvidedTokenBindingId();
      var tlsTokenBinding = binding == null ? null : Convert.ToBase64String(binding);
      var cookie = context.Options.CookieManager.GetRequestCookie(context.HttpContext, context.Options.CookieName);
      if (cookie != null)
      {
            var ticket = context.Options.TicketDataFormat.Unprotect(cookie, tlsTokenBinding);

            var expiresUtc = ticket.Properties.ExpiresUtc;
            var currentUtc = context.Options.SystemClock.UtcNow;
            if (expiresUtc != null && expiresUtc.Value < currentUtc)
            {
                  context.RedirectUri += "&p1=yourparameter";
            }
       }
       context.HttpContext.Response.Redirect(context.RedirectUri);

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接