web-dev-qa-db-ja.com

ASP.NETCookieの有効期限は常に1/1/000112:00AMです

次のコードを使用して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.NET3.5を使用しています

oK。 Gulzarからのリンクを読んだ後、cookieをチェックできないようです。HttpRequestで期限切れになりますか?リンクはcookie.Expiresが常にDateTime.MinValueに設定されていることを示唆しているように見えるため、サーバーはクライアントマシンの実際の時刻を知ることができないためですか?つまり、時間を自分でCookieに保存して確認する必要があるということですか?私の理解は正しいですか?

ありがとうシャンカー

27
Shankar

どのバージョンのasp.netを使用していますか?これは asp.netフォーラム で議論されました。

2
Gulzar Nazim

ここでの問題は、実際にはASP.NETにあるのではなく、ブラウザーによるhttpリクエストで提供される情報の量にあります。サーバー側で使用しているプラ​​ットフォームに関係なく、有効期限は取得できません。

質問で要約したように、HttpRequestオブジェクトによって提供されるHttpCookieオブジェクトのExpiresプロパティは、常に1/1/0001 12:00 AMに設定されます。これは、この有効期限情報、およびドメインやパスなどのプロパティが、リクエストの送信時にブラウザからサーバーに渡されないためです。送信されるCookie情報は、名前と値のみです。したがって、リクエスト内のCookieは、サーバー側では不明であるため、これらの「欠落している」フィールドのデフォルト値があります。

この背後にある理由は、Cookieの有効期限、ドメイン、パスの属性は、リクエストでCookieを渡すかどうかを決定するときに、ブラウザが使用することのみを目的としているためだと思います。サーバーは名前と値のみに関心があります。

Cookieの別の値として、有効期限を複製することを提案した回避策は、探している動作を取得する方法です。

60
Andy Rose

この問題を解決するために、プリンシパルにクレームを追加します。これを読み戻して、次のようにユーザーに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();
1
Jeff Nicholson

IPhoneでテストしたときにも同様の問題が発生しました。この問題は、iPhoneのデバイスに間違った日時が設定されていたため、Cookieの有効期限をdatetime.now.adddays(-1)に設定してもCookieの有効期限が切れなかったことが原因でした。

0
drinu82

リンクで説明されているバージョンの問題は役に立ちませんでした。基本的に、ASP.NETCookieは最悪です。有効期限を自分でCookieに保存し、リクエストごとに確認する必要がありました。

0
Shankar