31

我正在使用以下代码设置 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 的链接后,我似乎根本无法检查 HttpRequest 上的 cookie.Expires 吗?因为链接似乎表明 cookie.Expires 始终设置为 DateTime.MinValue 因为服务器永远无法知道客户端计算机上的实际时间?所以这意味着我必须自己将时间存储在cookie中并检查它?我的理解正确吗?

谢谢尚卡尔

4

6 回答 6

66

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

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

我猜这背后的原因是 cookie 的到期、域和路径属性仅用于浏览器在决定是否应在请求中传递 cookie 以及服务器只对名称和值感兴趣。

您建议将到期时间复制为 cookie 的另一个值的解决方法是获得您正在寻找的行为的一种方法。

于 2009-01-20T11:51:11.697 回答
5

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

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

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

呼叫MeLaNN

于 2009-10-08T15:56:28.840 回答
2

为了解决这个问题,我向主体添加了一个声明,然后我可以读取该声明并向用户显示 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();
于 2015-08-08T04:53:06.073 回答
0

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

于 2009-01-02T06:54:05.437 回答
0

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

于 2013-01-09T14:45:30.417 回答
0

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

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

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

此外,解决方法是在该 cookie 上存储另一个值来确定到期日期(如果你真的需要它)

参考:使用 HTTP cookie

于 2020-10-30T10:17:09.033 回答