ASP.NET cookie到期时间始终为1/1/0001 12:00 AM

时间:2008-10-13 17:11:03

标签: asp.net cookies

我正在使用以下代码设置Cookie到期时间:


// remove existing cookies.
request.Cookies.Clear();
response.Cookies.Clear();

// ... serialize and encrypt my data ...

// now set the cookie.
HttpCookie cookie = new HttpCookie(AuthCookieName, encrypted);
cookie.Expires = DateTime.Now.Add(TimeSpan.FromHours(CookieTimeOutHours));
cookie.HttpOnly = true;
response.Cookies.Add(cookie);

// redirect to different page

当我在另一页读取cookie超时时,我得到1/1/0001 12:00 AM。如果有人可以帮我解决问题,我会很感激。我正在使用ASP.NET 3.5

确定。看完Gulzar的链接后,似乎我无法检查cookie.Expires上的HttpRequest根本没有?因为链接似乎暗示cookie.Expires总是设置为DateTime.MinValue,因为服务器永远不知道客户端计算机上的实际时间?所以这意味着我必须自己将时间存储在cookie中并检查它?我的理解是否正确?

感谢 香卡

7 个答案:

答案 0 :(得分:59)

这里的问题并不在于ASP.NET,而在于浏览器在http请求中提供的信息量。无论您在服务器端使用的平台如何,都无法获得到期日期。

正如您在问题中总结的那样,HttpRequest对象提供的HttpCookie对象的Expires属性始终设置为1/1/0001 12:00 AM。 这是因为当发送请求时,浏览器不会将此到期信息以及域和路径等属性传递给服务器。发送的唯一cookie信息是名称和值。因此,请求中的cookie将具有这些“缺失”字段的默认值,因为它们在服务器端是未知的。

我猜这背后的原因是,cookie的expiry,domain和path属性仅供浏览器在决定是否应该在请求中传递cookie时使用并且服务器只对名称和值感兴趣。

你周围的工作建议复制到期时间,因为cookie的另一个值是获取你正在寻找的行为的一种方式。

答案 1 :(得分:4)

起初我也很失望为什么Request cookie没有实际的Expires值。使用Fiddler2调试http后。我知道.NET没有错,相反,http协议就是为什么请求cookie表现得像那样。

如果您在应用和浏览器之间使用Fiddler。您可以看到响应cookie正确发送到具有所有域,路径,过期,安全和httponly的浏览器。但是,http cookie标头中的下一个Request cookie没有expires值,它只有cookie名称和值。浏览器负责发送此请求标头,我相信是因为http协议。原因是因为最小化大小和Web服务器不需要检查它,因为它们实际上设置了所有值。他们应该注意。

因此您无需检查Web请求的过期值,因为您已经知道日期。只是,如果您收到cookie,则意味着cookie尚未过期。设置过期后,浏览器将处理到期日期。如果要更改过期,只需在响应中设置新值。

CallMeLaNN

答案 2 :(得分:2)

您使用的是哪个版本的asp.net?这在asp.net forum中进行了讨论。

答案 3 :(得分:1)

为了解决这个问题,我向主体添加了一个声明,然后我可以回读并向用户显示cookie到期时间,如下所示:

    public static void Configuration(IAppBuilder app)
    {

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString(string.Format("~/Login.aspx"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SetExpiryClaim 
            }
        });

        app.MapSignalR();
    }


    private static Task SetExpiryClaim(CookieValidateIdentityContext context)
    {
        var contextExpireUtc = context.Properties.ExpiresUtc;

        var claimTypeName = "contextExpireUtc";
        var identity = context.Identity;

        Claim contextExpiryClaim;

        if (identity.HasClaim(c => c.Type == claimTypeName))
        {
            contextExpiryClaim = identity.FindFirst(claimTypeName);
            identity.RemoveClaim(contextExpiryClaim);
        }
        contextExpiryClaim = new Claim(claimTypeName, contextExpireUtc.ToString());
        context.Identity.AddClaim(contextExpiryClaim);

        return Task.FromResult(true);
    }

然后您可以通过

从ClaimsPrinciple中检索到期时间
    ClaimsPrincipal principle = Thread.CurrentPrincipal as ClaimsPrincipal;
    DateTime contextExpiry = principle.Claims.First(p => p.Type == "contextExpireUtc").Value.AsDateTime();

答案 4 :(得分:0)

链接中讨论的版本问题没有帮助。基本上ASP.NET cookie糟透了。我必须自己将过期日期时间存储在cookie中,并在每个请求中检查它。

答案 5 :(得分:0)

使用Iphone测试时遇到了类似的问题。问题是由于Iphone在设备上设置了错误的日期时间,因此将cookie过期日期设置为datetime.now.adddays(-1)没有使cookie过期

答案 6 :(得分:0)

来自浏览器的请求仅发送namevalue个cookie,如下所示:

GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

因此,这在ASP.NET中不是问题。并且如在某些答案和评论中所提到的,到期日期是确定是否将该Cookie发送到服务器。因此,如果Cookie过期,则它将在服务器上为null

另外,解决方法是在该Cookie上存储另一个值,该值确定到期日期(如果您确实需要)

参考:Using HTTP cookies