Shankar
Shankar

Reputation: 1656

ASP.NET cookie expiration time is always 1/1/0001 12:00 AM

I'm setting the cookie expiration using the following code:


// 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

When I read the cookie timeout in the other page I'm getting 1/1/0001 12:00 AM. If someone can help me figure out the problem, I'll appreciate it. I'm using ASP.NET 3.5

ok. after reading the links from Gulzar, it appears that I cannot check cookie.Expires on the HttpRequest at all? Because the links seem to suggest that cookie.Expires is always set to DateTime.MinValue because the server can never know the actual time on the client machine? So this means I have to store the time inside the cookie myself and check it? Is my understanding correct?

thanks Shankar

Upvotes: 31

Views: 37604

Answers (6)

Ali Kleit
Ali Kleit

Reputation: 3649

A request from a browser sends only the name and value of the cookies as follows:

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

So this is not a problem in ASP.NET. And as mentioned in some answers and comments the expiration date is to determine whether to send that cookie to the server or not. So if the cookie was expired, it would be null on the server.

Also the workaround would be storing another value on that cookie that determines the expiry date (if you really need it)

Reference: Using HTTP cookies

Upvotes: 0

Jeff Nicholson
Jeff Nicholson

Reputation: 21

To solve this problem I add a claim to the principal which I can then read back and display the cookie expiry time to the user as follows:

    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);
    }

Then you are able to retrieve the expiry time later from the ClaimsPrinciple by

    ClaimsPrincipal principle = Thread.CurrentPrincipal as ClaimsPrincipal;
    DateTime contextExpiry = principle.Claims.First(p => p.Type == "contextExpireUtc").Value.AsDateTime();

Upvotes: 2

drinu82
drinu82

Reputation: 1

I had a similar problem when testing with an Iphone. The problem was due to the Iphone having the wrong date time set on the device, thus setting the cookie expire date to datetime.now.adddays(-1) did not expire the cookie

Upvotes: 0

Andy Rose
Andy Rose

Reputation: 17014

The problem here doesn't really lie with ASP.NET but with the amount of information that is provided in the http request by browsers. The expiry date would be unobtainable regardless of the platform you are using on the server side.

As you have summarised yourself in your question the Expires property of the HttpCookie object that is provided by the HttpRequest object is always set to 1/1/0001 12:00 AM. This is because this expiry information, as well as the properties such as domain and path, are not passed by the browser to the server when it sends a request. The only cookie information that is sent is the name and value(s). Therefore cookies in the request will have default values for these 'missing' fields as they are unknown on the server side.

I would guess the reason behind this is that the expiry, domain and path attributes of a cookie are only intended to be used by the browser when it is making a decision as to whether it should pass a cookie in a request or not and that the server is only interested in the name and value(s).

The work around you have suggested of duplicating the expiry time as another value of the cookie is a way to get the behaviour you are looking for.

Upvotes: 69

CallMeLaNN
CallMeLaNN

Reputation: 8578

At first I also disappointed why Request cookie doesn't have the actual Expires value. After debugging the http by using Fiddler2. I know that .NET was not wrong, instead, http protocol is the answer why Request cookies behaving like that.

If you use Fiddler between your app and the browser. You can see the Response cookie sent correctly to browser with all domain, path, expires, secure and httponly. However next Request cookie in http cookie header doesn't have the expires value, it only cookie name and value. Browser responsible to send this request header and I believe that is because http protocol. The reason why is because to minimize size and web server doesn't need to check it since they actually set all the values. They should notice.

So you no need to check the expires value on web request since you already know the date. Just, if you receive the cookie back that means the cookie is not yet expired. Once you set the expires, browser will handle the expiry. If you want to change the expires, just set the new value on the response.

CallMeLaNN

Upvotes: 5

Shankar
Shankar

Reputation: 1656

The version problem discussed in the link was not helpful. Basically ASP.NET cookie sucks. I had to store the expiration date time inside the cookie myself and check it in every request.

Upvotes: 0

Related Questions