次の方法で共有


ASP.NET の Cookie の概要

更新 : 2007 年 11 月

Cookie は、要求およびページと共に Web サーバーとクライアント間でやり取りされる少量のテキストです。Cookie には、ユーザーがサイトを訪問するたびに Web アプリケーションが読み込むことができる情報が格納されます。

このトピックの内容は次のとおりです。

  • シナリオ

  • 背景

  • コード例

  • クラス リファレンス

  • その他のリソース

  • 新機能

シナリオ

Web アプリケーションは Cookie を使用してユーザー固有情報を格納できます。たとえば、サイトを訪問したユーザーに Cookie を使用してユーザー設定などの情報を格納できます。ユーザーが再び Web サイトを訪問すると、アプリケーションは以前に格納した情報を取得できます。

ページのトップへ

背景

Cookie は、要求およびページと共に Web サーバーとクライアント間でやり取りされる少量のテキストです。Cookie には、ユーザーがサイトを訪問するたびに Web アプリケーションが読み込むことができる情報が格納されます。

たとえば、ユーザーがサイトのページを要求したときにアプリケーションがページと共に日時を含む Cookie を送信すると、ブラウザはページと共に Cookie を取得してユーザーのハード ディスクのフォルダに格納します。

その後に、ユーザーが同じサイトのページを再び要求すると、URL を入力した時点でブラウザはローカルのハード ディスクを確認して URL に関連付けられている Cookie を探します。Cookie がある場合、ブラウザはページの要求と共に Cookie をサイトに送信します。これによって、アプリケーションはユーザーが前回サイトを訪問した日時を確認できます。この情報を使用してユーザーにメッセージを表示したり、または有効期限をチェックできます。

Cookie は特定のページではなく Web サイトに関連付けられるため、ユーザーがサイト内のどのページを要求するかに関係なく、ブラウザとサーバーは Cookie 情報を交換できます。ユーザーがさまざまなサイトを訪問するに従って、サイトが Cookie をブラウザに送信するため、ブラウザはすべての Cookie を個別に格納します。

Cookie によって、Web サイトはビジターに関する情報を格納できます。一般に、Cookie は Web アプリケーションで連続性を維持するもので、状態を管理する方法の 1 つです。実際に情報を交換している短い時間を除いて、ブラウザと Web サーバーは切断されています。ユーザーが Web サーバーに行う各要求は、それぞれ独立して扱われます。ただし、多くの場合、Web サーバーにとってページを要求しているユーザーを認識できると便利です。たとえば、ショッピング サイトの Web サーバーは個々の顧客の行動を追跡して、ショッピング カートおよびその他のユーザー固有情報を管理します。したがって、Cookie はアプリケーションが処理を進めるために必要な適切な識別情報を提供する名刺のような役割を果たします。

Cookie は、Web サイトがユーザーを記憶するためのさまざまな用途に使用されます。たとえば、投票を行うサイトは Cookie を単なるブール値として使用し、ユーザーが重複して投票できないように、ブラウザが既に投票したかどうかを判別します。ユーザーにログオンを要求するサイトは、Cookie を使用してユーザーが既にログオンしているかどうかを記録して、資格情報を何度も入力する必要がないようにします。

ほとんどのブラウザは、4,096 バイトまでの Cookie をサポートします。このサイズの制限により、Cookie は、ユーザー ID など少量のデータを格納するのに適しています。Cookie に格納されたユーザー ID を使用して、ユーザーを識別して、データベースやその他のデータ ストアからユーザー情報を読み取ることができます。ユーザー情報の格納に関するセキュリティの意味については、この後の「Cookie とセキュリティ」を参照してください。

ブラウザにも、ユーザーのコンピュータに格納できるサイトあたりの Cookie の数の制限があります。ほとんどのブラウザはサイトあたり 20 までの Cookie を許可します。それを超える数の Cookie を保存すると、古い Cookie から破棄されます。すべてのサイトから受け入れる Cookie の総数に対する絶対限界 (通常は 300) を設定するブラウザもあります。

実際に影響を受ける Cookie の制限は、ブラウザが Cookie を拒否するようにユーザーが設定できるということです。P3P プライバシー ポリシーを定義して Web サイトのルートに置くと、より多くのブラウザがサイトから Cookie を受け入れるようになります。ただし、ユーザー固有情報を格納する場合に、Cookie の使用を避けて別の機構を使用する必要がある場合もあります。ユーザー情報を格納するための一般的な方法はセッション状態ですが、この後の「Cookie とセッション状態」で説明するように、セッション状態は Cookie に依存します。

ms178194.alert_note(ja-jp,VS.90).gifメモ :

状態の管理および Web アプリケーションに情報を保存する方法の詳細については、「ASP.NET の状態管理の概要」と「ASP.NET の状態管理に関する推奨事項」を参照してください。

アプリケーションにとって Cookie は非常に便利ですが、アプリケーションは Cookie を保存できることに依存すべきではありません。重要な機能をサポートするために Cookie は使用しないでください。Cookie に依存するアプリケーションは、ブラウザが Cookie を受け入れるかどうかをテストできます。この後の「ブラウザが Cookie を受け入れるかどうかの判定」を参照してください。

ブラウザは、ユーザーのシステムで Cookie を管理します。Cookie は、Cookies というコレクションを公開する HttpResponse オブジェクトを使用してブラウザに送信されます。HttpResponse オブジェクトには、Page クラスの Response プロパティとしてアクセスできます。ブラウザに送信するすべての Cookie は、このコレクションに追加する必要があります。Cookie を作成するときは、NameValue を指定します。各 Cookie には、ブラウザが後で読み込むときに識別できるように一意の名前が付けられます。Cookie は名前によって格納されるため、2 つの Cookie に同じ名前を付けると上書きされます。

Cookie には、有効期限の日時も設定できます。期限切れの Cookie は、ユーザーが Cookie を書き込んだサイトを訪問したときにブラウザによって削除されます。Cookie の有効期限は、アプリケーションにとって Cookie の値を有効にしておく必要がある期間に設定する必要があります。Cookie が期限切れにならないようにするには、有効期限を現在から 50 年に設定できます。

ms178194.alert_note(ja-jp,VS.90).gifメモ :

ユーザーは、ローカル コンピュータの Cookie をいつでも消去できます。長い有効期限の Cookie を保存しても、ユーザーがすべての Cookie を削除して Cookie に格納されているすべての設定を消去することがあります。

有効期限を設定しない場合も Cookie は作成されますが、ユーザーのハード ディスクには保存されません。代わりに、Cookie はユーザーのセッション情報の一部として維持されます。ユーザーがブラウザを閉じると、Cookie は破棄されます。このような非永続的な Cookie は、短時間だけ保存する必要がある情報またはセキュリティ上の理由からクライアント コンピュータのディスクに書き込むことができない情報に適しています。たとえば、非永続的な Cookie はユーザーが公共のコンピュータを使用する場合に便利です。この場合は、Cookie をディスクに書き込むべきではありません。

Cookie を Cookies コレクションに追加するには、いくつかの方法があります。Cookie を書き込む 2 つの方法の例を次に示します。

Response.Cookies("userName").Value = "patrick"
Response.Cookies("userName").Expires = DateTime.Now.AddDays(1)

Dim aCookie As New HttpCookie("lastVisit")
aCookie.Value = DateTime.Now.ToString()
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
Response.Cookies["userName"].Value = "patrick";
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(1);

HttpCookie aCookie = new HttpCookie("lastVisit");
aCookie.Value = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);

この例では、userName と lastVisit という 2 つの Cookie を Cookies コレクションに追加します。最初の Cookie では、Cookies コレクションの値を直接設定します。このようにして値をコレクションに追加できるのは、CookiesNameObjectCollectionBase 型の特殊なコレクションから派生しているからです。

2 番目のコード例では、HttpCookie 型のオブジェクトのインスタンスを作成し、プロパティを設定してから Add メソッドを使用して Cookies コレクションに追加します。HttpCookie オブジェクトをインスタンス化するときは、Cookie の名前をコンストラクタの一部として渡す必要があります。

この 2 つの例は共にブラウザに Cookie を書き込むという同じタスクを実行します。どちらの方法でも、有効期限の値は DateTime 型にする必要があります。ただし、lastVisited 値も日時の値です。すべての Cookie 値は文字列として格納されるため、日時の値も String 型に変換する必要があります。

Cookie には、ユーザー名や前回の訪問などの 1 つの値を格納できます。1 つの Cookie に複数の名前と値のペアを格納することもできます。名前と値のペアはサブキーと呼ばれます。サブキーは、URL のクエリ文字列のようにレイアウトされます。たとえば、userName と lastVisit という 2 つの Cookie を個別に作成する代わりに、userName と lastVisit という 2 つのサブキーを含む userInfo という単一の Cookie を作成することもできます。

サブキーを使用する理由はいくつかあります。まず、関連する情報または類似した情報は 1 つの Cookie にまとめると便利です。さらに、すべての情報が 1 つの Cookie にあるため、有効期限などの Cookie の属性をすべての情報に適用できます。逆に、異なる種類の情報にそれぞれの有効期限を割り当てる場合は、個別の Cookie に情報を格納する必要があります。

単一の Cookie に複数のサブキーを含めることにより、Cookie ファイルが占有する領域を節約することもできます。「Cookie の制限」で説明されているように、Cookie は一般に 4,096 バイトに制限され、サイトあたりで格納できる Cookie は 20 までです。単一の Cookie に複数のサブキーを含めることにより、サイトに割り当てられている Cookie の数を 20 以内に納めることができます。それぞれの Cookie は、格納する値の長さ (4,096 バイト以内) の他に有効期限などのオーバーヘッドに約 50 文字の領域を占有します。5 つの Cookie を使用する代わりに 1 つの Cookie に 5 つのサブキーを格納すると、個々の Cookie のオーバーヘッドを節約できるため、約 200 バイトを節約できます。

サブキーを含む Cookie を作成する場合は、単一の Cookie を記述するための一連の構文を使用できます。2 つのサブキーを含む同じ Cookie を記述する 2 つの方法の例を次に示します。

Response.Cookies("userInfo")("userName") = "patrick"
Response.Cookies("userInfo")("lastVisit") = DateTime.Now.ToString()
Response.Cookies("userInfo").Expires = DateTime.Now.AddDays(1)

Dim aCookie As New HttpCookie("userInfo")
aCookie.Values("userName") = "patrick"
aCookie.Values("lastVisit") = DateTime.Now.ToString()
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
Response.Cookies["userInfo"]["userName"] = "patrick";
Response.Cookies["userInfo"]["lastVisit"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);

HttpCookie aCookie = new HttpCookie("userInfo");
aCookie.Values["userName"] = "patrick";
aCookie.Values["lastVisit"] = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);

既定では、サイトのすべての Cookie はクライアントにまとめて格納され、サイトへの要求と共にすべての Cookie がサーバーに送信されます。言い換えれば、サイトのすべてのページは、そのサイトのすべての Cookie を受け取ります。ただし、Cookie のスコープを次の 2 つの方法で設定できます。

  • Cookie のスコープをサーバーの特定のフォルダに制限します。これによって、Cookie をサイトの特定のアプリケーションに限定できます。

  • ドメインに対してスコープを設定します。これによって、Cookie にアクセスできるサブドメインを指定できます。

Cookie をサーバーの特定のフォルダに制限するには、次の例のように Cookie の Path プロパティを設定します。

Dim appCookie As New HttpCookie("AppCookie")
appCookie.Value = "written " & DateTime.Now.ToString()
appCookie.Expires = DateTime.Now.AddDays(1)
appCookie.Path = "/Application1"
Response.Cookies.Add(appCookie)
HttpCookie appCookie = new HttpCookie("AppCookie");
appCookie.Value = "written " + DateTime.Now.ToString();
appCookie.Expires = DateTime.Now.AddDays(1);
appCookie.Path = "/Application1";
Response.Cookies.Add(appCookie);
ms178194.alert_note(ja-jp,VS.90).gifメモ :

前の例のように、Cookies コレクションに直接 Cookie を追加して記述することもできます。

パスには、サイトのルートの下の物理パスまたは仮想ルートを指定できます。その結果、Cookie は Application1 フォルダまたは仮想ルートのページのみが使用できるようになります。たとえば、www.contoso.com サイトでは、前の例で作成された Cookie は https://www.contoso.com/Application1/ というパスおよびそのフォルダの下のすべてのページで使用できます。ただし、Cookie は https://www.contoso.com/Application2/、https://www.contoso.com/ などの他のアプリケーションのページでは使用できません。

ms178194.alert_note(ja-jp,VS.90).gifメモ :

パスの大文字と小文字を区別するブラウザもあります。ユーザーがブラウザに URL をどのように入力するかを制御することはできませんが、特定のパスに関連付けられた Cookie に依存するアプリケーションは、作成するハイパーリンクの URL が Path プロパティ値の大文字/小文字の指定に一致する必要があります。

既定では、Cookie は特定のドメインに関連付けられます。たとえば、サイトが www.contoso.com で、ユーザーがこのサイトのページを要求したときに以前に書き込んだ Cookie をサーバーに送信するとします。これには、特定のパス値を指定した Cookie が含まれない場合もあります。サイトに contoso.com、sales.contoso.com、support.contoso.com などのサブドメインがある場合、Cookie を特定のサブドメインに関連付けることができます。そのためには、次の例のように Cookie の Domain プロパティを設定します。

Response.Cookies("domain").Value = DateTime.Now.ToString()
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "support.contoso.com"
Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "support.contoso.com";

このようにドメインを設定すると、Cookie は指定されたサブドメインのページのみで使用できます。次の例のように Domain プロパティを使用すると、複数のサブドメインで共有できる Cookie を作成することもできます。

Response.Cookies("domain").Value = DateTime.Now.ToString()
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "contoso.com"
Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "contoso.com";

これで、Cookie はプライマリ ドメインおよび sales.contoso.com ドメインと support.contoso.com ドメインで使用できるようになります。

ブラウザがサーバーに要求するときは、要求と共にサーバーに対する Cookie を送信します。ASP.NET アプリケーションでは、Page クラスの Request プロパティで使用できる HttpRequest オブジェクトを使用して Cookie を読み込みます。HttpRequest オブジェクトの構造は基本的に HttpResponse オブジェクトと同じなため、HttpResponse オブジェクトに Cookie を書き込んだ場合と同様にして HttpRequest オブジェクトから Cookie を読み込むことができます。username という Cookie の値を取得して Label コントロールに表示する 2 つの方法のコード例を次に示します。

If Not Request.Cookies("userName") Is Nothing Then
    Label1.Text = Server.HtmlEncode(Request.Cookies("userName").Value)
End If

If Not Request.Cookies("userName") Is Nothing Then
    Dim aCookie As HttpCookie = Request.Cookies("userName")
    Label1.Text = Server.HtmlEncode(aCookie.Value)
End If
if(Request.Cookies["userName"] != null)
    Label1.Text = Server.HtmlEncode(Request.Cookies["userName"].Value);

if(Request.Cookies["userName"] != null)
{
    HttpCookie aCookie = Request.Cookies["userName"];
    Label1.Text = Server.HtmlEncode(aCookie.Value);
}

Cookie が存在しない場合は NullReferenceException 例外が発生するため、Cookie の値を取得する前に Cookie が存在することを確認する必要があります。Cookie の内容をページに表示する前に HtmlEncode メソッドを呼び出してエンコードしていることにも注意してください。これによって、悪意のあるユーザーが Cookie に実行可能なスクリプトを追加することを防止できます。Cookie のセキュリティの詳細については、「Cookie とセキュリティ」を参照してください。

ms178194.alert_note(ja-jp,VS.90).gifメモ :

各ブラウザは個別に Cookie を格納するため、同じコンピュータの異なるブラウザが相互の Cookie を読み込む必要はありません。たとえば、Internet Explorer を使用してページをテストし、その後に別のブラウザで再びテストする場合、第 2 のブラウザは Internet Explorer が保存した Cookie を使用するわけではありません。

Cookie のサブキーの値の読み込む方法は、値の設定とほとんど同じです。サブキーの値を取得する 1 つの方法のコード例を次に示します。

If Not Request.Cookies("userInfo") Is Nothing Then
    Label1.Text = _
        Server.HtmlEncode(Request.Cookies("userInfo")("userName"))
    Label2.Text = _
        Server.HtmlEncode(Request.Cookies("userInfo")("lastVisit"))
End If
if(Request.Cookies["userInfo"] != null)
{
    Label1.Text = 
        Server.HtmlEncode(Request.Cookies["userInfo"]["userName"]);

    Label2.Text =
        Server.HtmlEncode(Request.Cookies["userInfo"]["lastVisit"]);
}

前のコード例では、以前に DateTime 値の文字列表現に設定した lastVisit サブキーの値を読み込みます。Cookie は値を文字列として格納するため、lastVisit 値を日付として使用する場合は、次の例のように適切な型に変換する必要があります。

Dim dt As DateTime
dt = DateTime.Parse(Request.Cookies("userInfo")("lastVisit"))
DateTime dt;
dt = DateTime.Parse(Request.Cookies["userInfo"]["lastVisit"]);

Cookie のサブキーは、NameValueCollection 型のコレクションになります。したがって、個々のサブキーを取得するもう 1 つの方法は、サブキーのコレクションを取得し、次の例のように名前によってサブキーの値を抽出することです。

If Not Request.Cookies("userInfo") Is Nothing Then
    Dim UserInfoCookieCollection As _
        System.Collections.Specialized.NameValueCollection
    UserInfoCookieCollection = Request.Cookies("userInfo").Values
    Label1.Text = _
        Server.HtmlEncode(UserInfoCookieCollection("userName"))
    Label2.Text = _
        Server.HtmlEncode(UserInfoCookieCollection("lastVisit"))
End If
if(Request.Cookies["userInfo"] != null)
{
    System.Collections.Specialized.NameValueCollection
        UserInfoCookieCollection;
       
    UserInfoCookieCollection = Request.Cookies["userInfo"].Values;
    Label1.Text = 
        Server.HtmlEncode(UserInfoCookieCollection["userName"]);
    Label2.Text =
        Server.HtmlEncode(UserInfoCookieCollection["lastVisit"]);
}

Cookie はブラウザが管理します。ブラウザは Cookie の有効期限の日時を使用して Cookie の保存を管理します。したがって、Cookie の名前と値を読み込むことはできますが、Cookie の有効期限の日時を読み込むことはできません。ブラウザは、有効期限の情報を含めずに Cookie 情報をサーバーに送信します。Cookie の Expires プロパティは、常にゼロの日時の値を返します。Cookie の有効期限が問題になる場合は、「Cookie の変更と削除」で説明されているように有効期限を再設定する必要があります。

ms178194.alert_note(ja-jp,VS.90).gifメモ :

Cookie がブラウザに送信される前に HttpResponse オブジェクトに設定した Cookie の Expires プロパティを読み込むことができます。ただし、有効期限を HttpRequest オブジェクトに戻すことはできません。

ページで使用できるすべての Cookie を読み込む必要がある場合もあります。ページで使用できるすべての Cookie の名前と値を読み込むには、次のようなコードを使用して Cookies コレクションにループを実行します。

Dim i As Integer
Dim output As System.Text.StringBuilder = New System.Text.StringBuilder
Dim aCookie As HttpCookie
For i = 0 to Request.Cookies.Count - 1
    aCookie = Request.Cookies(i)
    output.Append("Cookie name = " & Server.HtmlEncode(aCookie.Name) _
        & "<br />")
    output.Append("Cookie value = " & _
        Server.HtmlEncode(aCookie.Value) & "<br /><br />")
Next
Label1.Text = output.ToString()
System.Text.StringBuilder output = new System.Text.StringBuilder();
HttpCookie aCookie;
for(int i=0; i<Request.Cookies.Count; i++)
{
    aCookie = Request.Cookies[i];
    output.Append("Cookie name = " + Server.HtmlEncode(aCookie.Name) 
        + "<br />");
    output.Append("Cookie value = " + Server.HtmlEncode(aCookie.Value)
        + "<br /><br />");
}
Label1.Text = output.ToString();
ms178194.alert_note(ja-jp,VS.90).gifメモ :

このコードを実行する際に ASP.NET_SessionId という Cookie が見つかる場合があります。これは、ASP.NET がセッションに一意の識別子を格納するために使用する Cookie です。このセッション Cookie は、ハード ディスクに永続化されません。セッション Cookie の詳細については、この後の「Cookie とセッション状態」を参照してください。

前の例の制限は、Cookie にサブキーがある場合、サブキーが単一の名前/値の文字列として表示されることです。Cookie の HasKeys プロパティを確認すると、Cookie にサブキーがあるかどうかを判定できます。サブキーがある場合は、サブキー コレクションを読み込んで個々のサブキーの名前と値を取得できます。サブキーの値は、インデックス値を使用して Values コレクションから直接読み込むこともできます。対応するサブキーの名前は、配列文字列を返す Values コレクションの AllKeys メンバから取得できます。Values コレクションの Keys メンバを使用することもできます。ただし、AllKeys プロパティは最初にアクセスされたときにキャッシュされます。これとは対照的に、Keys プロパティはアクセスされるたびに配列を構築します。そのために、AllKeys プロパティは同じページの要求における 2 回目以降のアクセスがはるかに高速になります。

前の例を変更した例を次に示します。この例では、HasKeys プロパティを使用してサブキーをテストし、サブキーが検出されると、Values コレクションからサブキーを取得します。

Dim i As Integer
Dim j As Integer
Dim output As System.Text.StringBuilder = New StringBuilder()
Dim aCookie As HttpCookie
Dim subkeyName As String
Dim subkeyValue As String
For i = 0 To Request.Cookies.Count - 1
    aCookie = Request.Cookies(i)
    output.Append("Name = " & aCookie.Name & "<br />")
    If aCookie.HasKeys Then
        For j = 0 To aCookie.Values.Count - 1
            subkeyName = Server.HtmlEncode(aCookie.Values.AllKeys(j))
            subkeyValue = Server.HtmlEncode(aCookie.Values(j))
            output.Append("Subkey name = " & subkeyName & "<br />")
            output.Append("Subkey value = " & subkeyValue & _
                "<br /><br />")
        Next
    Else
        output.Append("Value = " & Server.HtmlEncode(aCookie.Value) & _
            "<br /><br />")
    End If
Next
Label1.Text = output.ToString()
for(int i=0; i<Request.Cookies.Count; i++)
{
    aCookie = Request.Cookies[i];
    output.Append("Name = " + aCookie.Name + "<br />");
    if(aCookie.HasKeys)
    {
        for(int j=0; j<aCookie.Values.Count; j++)
        {
            subkeyName = Server.HtmlEncode(aCookie.Values.AllKeys[j]);
            subkeyValue = Server.HtmlEncode(aCookie.Values[j]);
            output.Append("Subkey name = " + subkeyName + "<br />");
            output.Append("Subkey value = " + subkeyValue + 
                "<br /><br />");
        }
    }
    else
    {
        output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +
            "<br /><br />");
    }
}
Label1.Text = output.ToString();

次の例のように、サブキーを NameValueCollection オブジェクトとして抽出することもできます。

Dim i As Integer
Dim j As Integer
Dim output As System.Text.StringBuilder = New StringBuilder()
Dim aCookie As HttpCookie
Dim subkeyName As String
Dim subkeyValue As String
For i = 0 To Request.Cookies.Count - 1
    aCookie = Request.Cookies(i)
    output.Append("Name = " & aCookie.Name & "<br />")
    If aCookie.HasKeys Then
        Dim CookieValues As _
            System.Collections.Specialized.NameValueCollection = _
                aCookie.Values
        Dim CookieValueNames() As String = CookieValues.AllKeys
        For j = 0 To CookieValues.Count - 1
            subkeyName = Server.HtmlEncode(CookieValueNames(j))
            subkeyValue = Server.HtmlEncode(CookieValues(j))
            output.Append("Subkey name = " & subkeyName & "<br />")
            output.Append("Subkey value = " & subkeyValue & _
                "<br /><br />")
        Next
    Else
        output.Append("Value = " & Server.HtmlEncode(aCookie.Value) & _
            "<br /><br />")
    End If
Next
Label1.Text = output.ToString
System.Text.StringBuilder output = new System.Text.StringBuilder();
HttpCookie aCookie;
string subkeyName;
string subkeyValue;

for (int i = 0; i < Request.Cookies.Count; i++)
{
    aCookie = Request.Cookies[i];
    output.Append("Name = " + aCookie.Name + "<br />");
    if (aCookie.HasKeys)
    {
        System.Collections.Specialized.NameValueCollection CookieValues = 
            aCookie.Values;
        string[] CookieValueNames = CookieValues.AllKeys;
        for (int j = 0; j < CookieValues.Count; j++)
        {
            subkeyName = Server.HtmlEncode(CookieValueNames[j]);
            subkeyValue = Server.HtmlEncode(CookieValues[j]);
            output.Append("Subkey name = " + subkeyName + "<br />");
            output.Append("Subkey value = " + subkeyValue + 
                "<br /><br />");
        }
    }
    else
    {
        output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +
            "<br /><br />");
    }
}
Label1.Text = output.ToString();

Cookie を直接変更することはできません。Cookie を変更するには、新しい値を使用して新しい Cookie を作成し、ブラウザに送信してクライアントにある古いバージョンを上書きします。ユーザーのサイト訪問の回数を格納する Cookie の値を変更するコード例を次に示します。

Dim counter As Integer
If Request.Cookies("counter") Is Nothing Then
    counter = 0
Else
    counter = Int32.Parse(Request.Cookies("counter").Value)
End If
counter += 1
Response.Cookies("counter").Value = counter.ToString
Response.Cookies("counter").Expires = DateTime.Now.AddDays(1)
int counter;
if (Request.Cookies["counter"] == null)
    counter = 0;
else
{
    counter = int.Parse(Request.Cookies["counter"].Value);
}
counter++;

Response.Cookies["counter"].Value = counter.ToString();
Response.Cookies["counter"].Expires = DateTime.Now.AddDays(1);

Cookie をユーザーのハード ディスクから物理的に削除することは変更操作の変形です。Cookie はユーザーのコンピュータにあるため、直接削除することはできません。ただし、ブラウザに Cookie を削除させることはできます。その方法は、削除する Cookie と同じ名前で新しい Cookie を作成し、Cookie の有効期限を今日の日付より前に設定することです。ブラウザが Cookie の有効期限をチェックする際に、期限切れになっている Cookie が削除されます。アプリケーションが使用するすべての Cookie を削除する 1 つの方法のコード例を次に示します。

Dim aCookie As HttpCookie
Dim i As Integer
Dim cookieName As String
Dim limit As Integer = Request.Cookies.Count - 1
For i = 0 To limit
    cookieName = Request.Cookies(i).Name
    aCookie = New HttpCookie(cookieName)
    aCookie.Expires = DateTime.Now.AddDays(-1)
    Response.Cookies.Add(aCookie)
Next
HttpCookie aCookie;
string cookieName;
int limit = Request.Cookies.Count;
for (int i=0; i<limit; i++)
{
    cookieName = Request.Cookies[i].Name;
    aCookie = new HttpCookie(cookieName);
    aCookie.Expires = DateTime.Now.AddDays(-1);
    Response.Cookies.Add(aCookie);
}

サブキーの変更または削除

次の例に示すように、個々のサブキーの変更は作成する場合と同じです。

Response.Cookies("userInfo")("lastVisit") = DateTime.Now.ToString()
Response.Cookies("userInfo").Expires = DateTime.Now.AddDays(1)
Response.Cookies["userInfo"]["lastVisit"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);

個々のサブキーを削除するには、サブキーを保持する Cookie の Values コレクションを操作します。まず、Cookies オブジェクトから Cookie を取得して再作成します。次に Values コレクションの Remove メソッドを呼び出して、Remove メソッドに削除するサブキーの名前を渡します。次に、Cookie が変更された状態でブラウザに送信されるように Cookies コレクションに追加します。サブキーを削除する方法の例を次に示します。この例では、削除するサブキーの名前を変数で指定しています。

Dim subkeyName As String
subkeyName = "userName"
Dim aCookie As HttpCookie = Request.Cookies("userInfo")
aCookie.Values.Remove(subkeyName)
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
string subkeyName;
subkeyName = "userName";
HttpCookie aCookie = Request.Cookies["userInfo"];
aCookie.Values.Remove(subkeyName);
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);

Cookie のセキュリティの問題は、クライアントからデータを取得する場合と同様です。アプリケーションでは、Cookie はユーザー入力のもう 1 つの形式であるため、チェックとなりすましの対象となります。Cookie はユーザーのローカル コンピュータに格納されるため、ユーザーは少なくとも Cookie に格納されているデータを参照できます。ユーザーはブラウザが Cookie を送信する前に変更することもできます。

Cookie には、ユーザー名、パスワード、クレジット カードの番号などの重要情報を決して保存しないでください。ユーザーまたは Cookie を盗む可能性がある人物に入手されては困る情報は、Cookie に保存しないでください。

同様に、Cookie から取得する情報を安易に信用しないようにしてください。Cookie のデータは、それを書き込んだ時点と同じであると仮定しないでください。Cookie の値には、ユーザーが Web ページに入力したデータと同様の安全対策を適用してください。このトピックの以前の例では、ユーザーから取得した情報を表示する前にエンコードする場合と同様に、Cookie の値をページに表示する前に内容を HTML エンコードする例を示しました。

Cookie はブラウザとサーバー間をプレーンテキストで送信されるため、Web トラフィックの横取りによって Cookie が読み取られる可能性があります。接続が SSL (Secure Sockets Layer) を使用する場合のみ Cookie を転送するように Cookie のプロパティを設定することもできます。SSL はユーザーのコンピュータにある Cookie を読み取りや変更から保護しませんが、Cookie が暗号化されるので転送中の読み取りは防止できます。詳細については、「Web アプリケーションのセキュリティに関する基本的な対策」を参照してください。

ブラウザは Cookie を拒否するように設定できます。Cookie を書き込むことができない場合にもエラーは発生しません。同様に、ブラウザは現在の Cookie の設定に関する情報をサーバーに送信しません。

ms178194.alert_note(ja-jp,VS.90).gifメモ :

Cookies プロパティは、Cookie が有効になっているかどうかを示しません。このプロパティは、現在のブラウザが Cookie をサポートするかどうかを示すだけです。

ブラウザが Cookie を受け入れるかどうかを判定する 1 つの方法は、Cookie を書き込んでから再び読み込んでみることです。書き込んだ Cookie を読み込むことができない場合は、ブラウザで Cookie が無効になっていると見なすことができます。

ブラウザが Cookie を受け入れるかどうかをテストするコード例を次に示します。この例は、2 ページで構成されます。最初のページでは Cookie を書き込み、ブラウザを 2 ページ目にリダイレクトします。2 ページ目では、Cookie を読み込みます。次に、ブラウザを最初のページにリダイレクトし、テストの結果を含むクエリ文字列変数を URL に追加します。

最初のページのコードは次のようになります。

Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        If Request.QueryString("AcceptsCookies") Is Nothing Then
            Response.Cookies("TestCookie").Value = "ok"
            Response.Cookies("TestCookie").Expires = _
                DateTime.Now.AddMinutes(1)
            Response.Redirect("TestForCookies.aspx?redirect=" & _
                Server.UrlEncode(Request.Url.ToString))
        Else
            Label1.Text = "Accept cookies = " & _
                Server.UrlEncode(Request.QueryString("AcceptsCookies"))
        End If
    End If
End Sub
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        if (Request.QueryString["AcceptsCookies"] == null)
        {
            Response.Cookies["TestCookie"].Value = "ok";
            Response.Cookies["TestCookie"].Expires =
                DateTime.Now.AddMinutes(1);
            Response.Redirect("TestForCookies.aspx?redirect=" +
                Server.UrlEncode(Request.Url.ToString()));
        }
        else
        {
            Label1.Text = "Accept cookies = " +
                Server.UrlEncode(
                Request.QueryString["AcceptsCookies"]);
        }
    }
}

このページでは、まずポストバックかどうかを判別し、ポストバックではない場合は、テストの結果を含むクエリ文字列変数名 AcceptsCookies を探します。クエリ文字列変数がない場合はテストが完了していないため、TestCookie という Cookie を書き込みます。Cookie を書き込んだ後、Redirect を呼び出して、テスト ページ TestForCookies.aspx に転送します。テスト ページの URL に、現在のページの URL が含まれる redirect という名前のクエリ文字列変数が追加されます。これによって、テストの実行後、このページにリダイレクトして戻ることができます。

テスト ページにはコードのみを記述し、コントロールを含める必要はありません。テスト ページのコード例を次に示します。

Sub Page_Load()
    Dim redirect As String = Request.QueryString("redirect")
    Dim acceptsCookies As String
    If Request.Cookies("TestCookie") Is Nothing Then
        acceptsCookies = "no"
    Else
        acceptsCookies = "yes"
        ' Delete test cookie.
        Response.Cookies("TestCookie").Expires = _
            DateTime.Now.AddDays(-1)
    End If
    Response.Redirect(redirect & "?AcceptsCookies=" & acceptsCookies, _
       True)
End Sub
protected void Page_Load(object sender, EventArgs e)
{
    string redirect = Request.QueryString["redirect"];
    string acceptsCookies;
    if(Request.Cookies["TestCookie"] ==null)
        acceptsCookies = "no";
    else
    {
        acceptsCookies = "yes";
        // Delete test cookie.
        Response.Cookies["TestCookie"].Expires = 
            DateTime.Now.AddDays(-1);
    }
    Response.Redirect(redirect + "?AcceptsCookies=" + acceptsCookies,
    true);
}

リダイレクト用クエリ文字列変数を読み込んだ後に、コードは Cookie の読み込みを試みます。ハウスキーピングのために、Cookie がある場合はすぐに削除します。テストが完了すると、コードは redirect クエリ文字列変数に含まれる URL を使用して新しい URL を作成します。新しい URL には、テストの結果を含むクエリ文字列変数も含まれます。最後に、新しい URL を使用してブラウザを元のページにリダイレクトします。

この例を改善して、データベースなどの永続的な格納場所に Cookie のテスト結果を保存すると、ユーザーが元のページを表示するたびにテストを繰り返す必要がなくなります。既定でテストの結果をセッション状態に格納するには Cookie が必要です。

ユーザーがサイトを訪問すると、サーバーはユーザーの訪問中存続する一意のセッションを確立します。ASP.NET は、各セッションに対してアプリケーションがユーザー固有情報を格納できるセッション ステータス情報を維持します。詳細については、「ASP.NET セッション状態の概要」を参照してください。

ASP.NET は、ユーザーをサーバーのセッション状態の情報にマップできるように、各ユーザーのセッション ID を追跡する必要があります。既定では、ASP.NET は非永続的な Cookie にセッション状態を格納します。ただし、ユーザーがブラウザの Cookie を無効にしている場合は、セッション状態の情報を Cookie に格納できません。

ASP.NET には、Cookie なしのセッションのための代替手段があります。アプリケーションは、セッション ID を Cookie ではなく、サイトのページの URL に格納するように構成できます。アプリケーションがセッション状態に依存する場合は、Cookie なしのセッションを使用するように構成することを考慮します。ただし、ユーザーのセッションがアクティブな状態で同僚に URL を送信するなどの特別の状況で他のユーザーと URL を共有する場合は、両方のユーザーが同じセッションを共有することになるため、予測できない結果になることがあります。アプリケーションが Cookie なしのセッションを使用するように構成する方法の詳細については、「ASP.NET の状態管理の概要」を参照してください。

ページのトップへ

コード例

クイック スタート

Managing Application State

"方法" トピックと "チュートリアル" トピック

方法 : WCF 認証サービスから認証 Cookie をカスタマイズする

ページのトップへ

クラス リファレンス

HttpCookie

個々の HTTP Cookie をタイプ セーフな方法で作成および操作できるようにします。

Cookies

応答の Cookie コレクションを取得します。

Cookies

クライアントから送信された Cookie のコレクションを取得します。

ページのトップへ

その他のリソース

ページのトップへ

新機能

ページのトップへ

参照

概念

ASP.NET の状態管理の概要

参照

ページのトップへ