《第4回》 パスワードを限定公開?!

Cookieを焼きましょう。「ぬぽぬぽ」と、さりげなくメンバーだけに公開。

●ぬぽぬぽ管理
 HPを作ると、知り合いや、よく訪れてくれるメンバーだけに公開したいページを持
ちたくなる。それには、httpサーバに、パスワード制限をかければよい。
 しかし、パスワードは、ブラウザ側で自動保存されてしまうため、できれば、パスワ
ードをときどき変えたい。だって、マンガ喫茶からアクセスしたユーザーのPCから、
秘密写真か何かを見られたら、ど〜する?

 では、パスワードを月1回変えよう。ところが困った。パスワードを変えるたびにメ
ールで告知すると、どれが最新のパスワードか、ユーザーが管理できなくなるのだ。

「そんなことじゃダメだ!最新のパスワードは、×××だよ!」と、怒りまくるのもい
いだろう。だが、そんなキチキチ管理で熱くなっても、ユーザーは、また聞いてくる。

「パスワード何だっけ?」。
 そこで、やってられっかと、ダレダレ管理になる状況。「ユーザー・123 パスワ
ード・456」。これでいーじゃん!……ホント?

 今回は、ダレダレ管理とキチキチ管理の中間、「ぬぽぬぽ管理」を紹介しよう。パス
ワードを、堂々と、ネットで限定公開する手法である。なあるほど。……え?「堂々」
と「限定」?!

 要するに、今回は、あるテキスト・ファイルを、パスワードなしで、限定的に堂々と
公開する方法を見る。パスワードに限らず、恥ずかしい秘密日記や、ちょっとした論文
などを、パスワードなしで公開する方法である。


●Cookieを焼く
 そこで登場するのが、「cookie」である。「cookie」とは、何も、「サ
イト訪問回数」や、「連続カキコ抑制」をするためのものじゃないのだ。ってか、「c
ookie」って何?

 「cookie」とは、ユーザー側のPC(クライアントPC)に、webサーバと
のやり取りで使う情報を保存しておく仕組みのこと。

 PCのHDDの、「\Documents and Settings\ログオン名
\Local Settings\Temporary Internet File
s\なんとか」(win2000 IE)とか、「\Program Files\N
etscape\Users\ユーザ名\cookies.txt」(ネスケ)などに
、テキスト・ファイルとして保存されている。

 これを利用して、
@決めた期間内(たとえば1日以内)
A決めた回数アクセス(たとえば7回)
の条件を満たしたユーザーだけに、用意したテキスト・ファイルを表示するcgiを作
ろう。

 つまり、はじめてそのページを見たユーザーにはダミーのページが表示され、7回リ
ロードしたユーザーにだけパスワードや秘密日記を見せる。
 さらに、1日以内にそのページをアクセスした場合は秘密ファイルを表示するが、1
日以上置いてアクセスした場合にはリセットがかかり、再び「ダミー・ページ」を7回
リロードしてもらう、というもの。

 もう安心。これからは、1回だけ方法を教えれば、他のユーザーから問い合わせがく
るようなことはない。んー。なかなか。


●Cookieの読み込み、書き込み
 cookieの読み込み、書き込みは、実に簡単だ。

 読み込みは、環境変数「$ENV{'HTTP_COOKIE'}」の中に、まとめ
て格納されている。
 形式は、「x1=なんとか  ;x2=なんとか;」のように、「変数名=」の後に
「値」が格納され、変数の切れ目を「;」で表わす。なお、「値」の中に日本語があっ
た場合、URLエンコードされている。

 書き込みも実に簡単。「Content-Type: text/html」を、ブ
ラウザに送信する前に、cgiから情報を送ればよい。
 たとえば、「print "Set-Cookie: hoge1=xxxxx; 
hoge2=yyyyy; expires=Sat, 12-Dec-2050 0
0:00:00 GMT"」などである。「expires」のところは、cooki
eファイルの有効期限だが、今回は、この機能を使わないので、ずっと先の2050年
12月31を有効期限としている。


●プログラム
 リスト1を参照してほしい。秀丸などのエディタで、「eucコード」として保存す
ること。

 cookieの読み込みは、「&getCookie」をコールすれば、変数「$C
OOKIE{hoge}」に値が格納される。

 cookieの書き込みは、「print &setCookie("hoge",
 "xxxxx");」のようにすれば、変数「hoge」に「xxxxx」を書き込
める。

 変数のカスタマイズは、「$efdate = 1」と「$reload = 7」
、そして、「$mesg = "msg.txt"」の部分で行なえる。それぞれ、「
$efdate」は「有効期間日数」、「$reload」は「秘密ページが表示され
るまでのリロード回数」、そして、「$mesg」は「条件をパスしたユーザーに表示
したいテキスト・ファイル」である。

●CGI起動
 では、さっそく起動しよう。
 まず、「cookie.pl」を、「c:\Perl\cgi」などの、サーバの「
cgi-bin」ディレクトリに保存し、ローカルwebサーバを起動しよう。
 次に、ブラウザのアドレス欄に、「http://localhost/cgi-b
in/cookie.pl」と入力してリターンする。

 すると、「ようこそネコアザラシのHPへ。ねこねこ。テスト運営中。1998年…
…」などという、なんの意味もないダミー・メッセージが表示される。
 間違ってこのページを見た通りすがりの者は、このメッセージでやる気が失せ、どこ
かに去って行くだろう。日付も「1998年……」などと、かなり旧いテスト・ページ
を匂わせている。




 ところが、これを必死に(?)、7回、リロードすると、無事、リスト2のメッセー
ジ($mesgで指定したテキスト・ファイル)が表示される。



 最後にアクセスしてから、1日以内ならば、7回のリロードは免除される。

 もちろん、外に公開したサーバなら、インターネット公開できる。そのときは、「h
ttp://割り振られたIP/cgi-bin/cookie.pl」をアクセスす
る。
*
 cookieを目からウロコの手法に応用することで、パスワードなしで、秘密のメ
ッセージを見せることに成功した。われながら、実に華麗な方法だと言わねばなるまい
。

 ところで、「リロード×数回」という操作を忘れたユーザーから、「なんか変なメッ
セージが出て来るばっかりで、パスワード出てこないよ〜」と聞かれた場合は、いった
いどうするのか? ま、ユーザーや知人からのたまの連絡も嬉しいもんである…と、そ
のときは、スッパリあきらめよう(なら、このcgi必要ないじゃん?!)。
(辻豊史)

「今日からCGIプログラマー」
http://www.geocities.co.jp/SiliconValle
y-Cupertino/6103/

 

 リスト1 「cookie.pl」 cookieによる簡易セキュリティ
#!C:/Perl/bin/perl #cookie.pl #≪保存≫EUC+LFで保存すること #≪目的≫cookieを利用した簡易セキュリティ・チェック #≪使用法≫リロードを繰り返すと目的のページが表示される $efdate = 1;#---有効にしたい日数 $mesg = "msg.txt";#メッセージ・ファイル #---cookieの有効期間(2050年12月31日固定) $exp = " expires=Sat, 12-Dec-2050 00:00:00 GMT"; #---リロード回数更新(有効期間内のみ) #$ckok=0…期間外 1…期間内で回数が満たない 2…OK $nowreload = 1;&ckchk; if ($ckok != 0) {$nowreload = $COOKIE{REL}; $nowreload++;} #---有効期間計算・cookieセット $efsec = $efdate * 24 * 60 * 60;$eftime = time + $efsec; print &setCookie("REL", "$nowreload"); print &setCookie("ESTIME", "$eftime"); #---表示 require "./jcode.pl";#jcode.plを読み込む $title = "テストのページ";$maintit = "メンバーのページ"; ($ckok == 2) && ($title = $maintit);&head; if ($ckok == 2) {$line = "メンバー・ページ。<BR>$efdate 日以上アクセス しないと、履歴がクリアされるので、ここをリロード× $reload して。"; &lprint;open (IN , "< $mesg"); while (<IN>) { if (/^#/) {next;} $line = "$_<BR>";&lprint;} } else { $line = "ようこそネコアザラシのHPへ。ねこねこ。<BR> テスト運営中です。<BR>1998年10月1日";&lprint;} print "</BODY></HTML>"; #---Cookieに値を書き込むためのSet-Cookie:ヘッダを生成する #---日本語エンコード対応。 sub setCookie {local($tmp, $val); $val = $_[1]; $val =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; $tmp = "Set-Cookie: ";$tmp .= "$_[0]=$val; "; $tmp .= " ${exp};\n";return($tmp);} #---ヘッダ表示 sub head {$line ="Content-type: text/html\n\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD> <META http-equiv=Content-Type content=\"text/html; charset=x-sjis\"> <TITLE>$title</TITLE></HEAD><BODY>";&lprint;} #---sjis表示 sub lprint { &jcode'convert(*line,sjis);print $line;} #---cookieチェック #---Cookieの値を読み出す。日本語デコード対応。 sub getCookie { local($xx, $name, $value); for $xx (split(/; */, $ENV{'HTTP_COOKIE'})) { ($name, $value) = split(/=/, $xx); $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg; $COOKIE{$name} = $value;} } sub ckchk { $nowtime = time; $reload = 7;#---何回リロードするとチェックが外れるか $ckok = 0;&getCookie; ($COOKIE{ESTIME} > $nowtime) && ($ckok = 1); ($ckok == 1) && ($COOKIE{REL} >= $reload) && ($ckok++);}
 リスト2 「msg.txt」秘密メッセージ・ファイル
#メンバーに見せるメッセージのサンプル(euc保存) <BR><BR>で。今日のパスワードは、 User=shingo Pass=gorogoro。 4649!