cookie

前へ << 秘密情報の管理 画像生成 >> 次へ

cookie とは

cookie とは、ブラウザ側に個人情報を保存する仕組みです。 ある web 掲示板にメッセージを書き込んだとします。 そこで自分の名前とメールアドレスを入力します。 しかし、再び訪問したときに、以前に入力した名前やメールアドレスを 再度入力するのは面倒です。そういう場合に cookie を使います。
cookie はもともと Netscape 社が提唱したものです。 もともと cookie の仕様は、Netscape が公開している 仕様書 に記載されていました。これは Set-Cookie と Cookie というヘッダを使用するものでした。

その後、Netscape の仕様を追認・補完する形で RFC 2109 が公開されました。 その後、RFC 2965 で Set-Cookie2 と Cookie2 という新たな仕組みが提案されました。RFC 2965RFC 2109 を obsolete しているので、これに従うのであれば Set-Cookie・Cookie の使用はやめて、Set-Cookie2 と Cookie2 に移行すべきです。 ただし、理由は知りませんが、RFC 2965 方式の Set-Cookie2 と Cookie2 は人気がありません。 世の中の大半のブラウザ・web サーバは、Set-Cookie・Cookie 方式にしか対応していないと思われます。2005年 6月現在、少なくとも Mozilla と IE は Set-Cookie2 と Cookie2 に未対応で、Opera は対応済のようです。

よって、Cookie を利用する側としては、Set-Cookie・Cookie だけ知っておけば十分でしょう。

cookie とは、CGI プログラム側がブラウザに渡すデータです。 データを渡される側のブラウザは、どこの誰から受け取ったものかを記録し、 受け取ったデータを保存しておきます。 次回同じ URL にアクセスした場合は、ブラウザが WWW サーバに前回受け取った データを提出します。 ただし、WWW サーバが渡した cookie データをブラウザが受け取るかどうかは ブラウザの勝手です。次回のアクセス時にブラウザが WWW サーバに cookie データを 提出するかもブラウザの勝手です。

cookie というのは、ただの文字列でしかありません。 そのデータをどう解釈するかは、cookie を解釈する CGI プログラム次第です。

cookie をセット

cookie をセットする場合は、Set-Cookie: ヘッダを出力します。

cookie-set.cgi (実行結果)

    1: #!/usr/local/bin/perl
    2: 
    3: print <<'END';
    4: Content-type: text/html; charset=EUC-JP
    5: Set-Cookie: DATA=abc; expires=Mon, 30 Dec 2020 23:59:59 GMT
    6: 
    7: <HTML><BODY BGCOLOR=WHITE>
    8: <TT>Set-Cookie: DATA=abc; expires=Mon, 30 Dec 2020 23:59:59 GMT
    9: </TT>
   10: <BR>
   11: というデータをヘッダに出力しました。
   12: </BODY></HTML>
   13: END
この CGI プログラムを実行すると、ブラウザの設定によっては
[cookie 確認ダイアログ]
という確認ダイアログが出ます。ここで「確認」を押すと cookie を受け入れますが、「キャンセル」を押すと 渡された cookie データを記憶しません。
    5: Set-Cookie: DATA=abc; expires=Mon, 30 Dec 2020 23:59:59 GMT
ここでは、DATA=ABC という cookie データをセットしています。 最後に ; を付けることで、項目の終わりを表します。 次の expires は、この cookie データの有効期限を表します。 この cookie は世界標準時 (GMT) で「2020年12月30日 (月) 23:59:59」 で期限切れとなります。期限切れかどうかを判断するのはブラウザ側です。 次回アクセス時に、ブラウザは という動作をします。

cookie を取得

今度は cookie の取得です。まず、上の CGI にアクセスし、 cookie を受け取らないと何も表示されません。

cookie-get.cgi (実行結果)

    1: #!/usr/local/bin/perl
    2: 
    3: if ( $ENV{HTTP_COOKIE} ne '' ){
    4:     foreach ( split(/\s*;\s*/,$ENV{HTTP_COOKIE}) ){
    5:         foreach ( split(/\,/,$_) ){
    6:             my ($key,$value) = split(/=/,$_);
    7:             $value =~ tr/+/ /;
    8:             $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
    9:             $COOKIE{$key} = $value;
   10:         }
   11:     }
   12: }
   13: 
   14: print <<END;
   15: Content-type: text/html; charset=EUC-JP
   16: 
   17: <HTML><BODY BGCOLOR=WHITE>
   18: \$ENV{HTTP_COOKIE} = $ENV{HTTP_COOKIE}
   19: <P>
   20: END
   21: 
   22: foreach ( sort keys %COOKIE ){
   23:     print "$_ = $COOKIE{$_}<BR>\n";
   24: }
   25: 
   26: print "</BODY></HTML>\n";
$ENV{HTTP_COOKIE}

cookie を URL エンコード

完成版

cookie.cgi (実行結果)

    1: #!/usr/local/bin/perl
    2: 
    3: print "Content-type: text/html; charset=EUC-JP\n";
    4: 
    5: if ( $ENV{HTTP_COOKIE} ne '' ){
    6:     foreach ( split(/\s*;\s*/,$ENV{HTTP_COOKIE}) ){
    7:         foreach ( split(/\,/,$_) ){
    8:             ($key,$value) = split(/=/,$_);
    9:             $value =~ tr/+/ /;
   10:             $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
   11:             $COOKIE{$key} = $value;
   12:         }
   13:     }
   14: }
   15: 
   16: read(STDIN,$buf,$ENV{CONTENT_LENGTH});
   17: if ( $buf ne '' ){
   18:     foreach ( split(/\s*;\s*/,$ENV{HTTP_COOKIE}) ){
   19:         foreach ( split(/\,/,$_) ){
   20:             ($key,$value) = split(/=/,$_);
   21:             $value =~ tr/+/ /;
   22:             $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
   23:             $FORM{$key} = $value;
   24:         }
   25:     }
   26: }
   27: 
   28: if ( $FORM{COOKIE_FLAG} eq 'on' ){
   29:     ($name,$email,$url) = ($FORM{NAME},$FORM{EMAIL});
   30:     foreach ( $name,$email,$url ){        # URL エンコード
   31:         s/([^-_a-zA-Z0-9 ])/sprintf("%%%02lX",unpack("C",$1))/eg;
   32:         s/ /+/g;
   33:     }
   34:     $cookie_data =
   35:       "Set-Cookie: NAME=$name,EMAIL=$email,URL=$url; expires=Mon, 30 Dec 2020 23:59:59 GMT\n";
   36:     print $cookie_data;
   37: }
   38: 
   39: print "\n<HTML><BODY BGCOLOR=WHITE>\n";
   40: 
   41: if ( $ENV{HTTP_COOKIE} ){
   42:     print "受け取った cookie: $ENV{HTTP_COOKIE}<P>\n";
   43: }
   44: 
   45: if ( $cookie_data ){
   46:     print "セットした cookie: $cookie_data<P>\n";
   47: }
   48: 
   49: print <<END;
   50: <FORM METHOD=POST ACTION="$ENV{REQUEST_URI}">
   51: <TABLE>
   52:   <TR><TD>名前: <TD><INPUT TYPE=TEXT NAME=NAME VALUE=$COOKIE{NAME}>
   53:   <TR><TD>メールアドレス: <TD><INPUT TYPE=TEXT NAME=EMAIL VALUE=$COOKIE{EMAIL}>
   54:   <TR><TD>Cookie を利用する: <INPUT TYPE=CHECKBOX NAME=COOKIE_FLAG><BR>
   55:   <TR><TD><INPUT TYPE=SUBMIT VALUE=OK><BR>
   56: </TABLE>
   57: </FORM>
   58: </BODY></HTML>
   59: END

前へ << 秘密情報の管理 画像生成 >> 次へ

$Id: cookie.html,v 1.7 2006/02/12 11:08:29 68user Exp $