パスワードでアクセス制限


インターネット上のサイトやページをパスワードでロックし、不正アクセスを防ぐには、.htaccsess を使った基本認証か CGI を利用するのが普通であり、一般的なセキュリティを考えれば、それらを利用するに越したことはないと思います。
しかし JavaScript を使ってもっと簡単な方法でアクセス制限をすることができないか、私なりに考えてみました。

問題点は2つあります。

まず、パスワードを入力する方法には、1.パスワードダイアログに入力する、2.ページ上の入力フォームに入力する、の2つがありますが、ここでは1の方法を選びます。その理由はじきにわかると思います。
1つの例として、index.htm にパスワード制限サイトへのリンクを指定します。

<a href="check.htm"> メンバーズページへ </a>

次に、check.htm の <BODY>〜</BODY> 間に次のように書きます。(password の個所を自分が決めたパスワードに変えて下さい。)

<SCRIPT Language="JavaScript">
<!--
result=prompt("パスワードを入れて下さい","");
if(result != "password")
{
alert("パスワードが違います!")
location.href="caution.htm";
}
else
{
F=new Date();
S=F.getTime();
document.cookie="&chk="+S+"&end";
location.href="secret.htm";
}
//-->
</SCRIPT>

check.htm の特徴は、これだけです。文章などのコンテンツは要りません。
ユーザーが「メンバーズページ」へをクリックすると、パスワード入力を求めるダイアログが表示されます。 間違ったパスワードを入力したり、「キャンセル」をクリックすると、caution.htm に強制的にジャンプさせられます。 この caution.htm には「認証できませんでした」とでも書き、<a href="index.htm">「戻る」</a> を設定しておけばいいでしょう。

パスワードが正しければ、secret.htm へとジャンプしますが、その前に getTime() メソッドで1970年1月1日午前0時0分0秒から現在までの経過時間を1000分の1秒単位で取得し、これをユーザーの cookie ファイルに書き込みます。 (cookie を使う理由は、あとで述べます。)

これは、パスワードを求めるダイアログを index.htm ではなく、check.htm から呼び出している点がミソです。 check.htm が読み込まれたとき、ユーザーはパスワードを入力しなければならないので、このファイルのソース(パスワードが書いてある)を見ることができません。 しかも正しいパスワードを入力してもしなくても、ユーザーは強制的に別のページへジャンプさせられるので結局 check.htm のソースを見られずに終わります。 「戻る」ボタンを押して check.htm に戻ろうとしても、或いは check.htm のアドレスを直接入力しても、いつもパスワードダイアログに阻まれてソースを見ることができません。 しかしそれ以前に、この check.htm の介在に気づくユーザーは少ないでしょう。

しかしパスワードでのチェックに成功しても、secret.htm の URL を知られたら、もうパスワードの意味がなくなるのではないか、という問題が生じます。 そこで secret.htm の読み込みにもチェックを入れなければなりません。secret.htm の <BODY>〜</BODY> 間には、次のように書きます。

<SCRIPT Language="JavaScript">
<!--
F=new Date();
S=F.getTime();
R=document.cookie;
start=R.indexOf("&chk=",0);
end=R.indexOf("&end",0);
X=R.substring(start+5,end);
if((S-X) > 30000 || R == "")
{
alert ("警告\n不正なアクセスです。");
location.href="check.htm";
}
else document.write("(ページの内容を表すタグを書く)");
//-->
</SCRIPT>

secret.htm がロードされたとき、ここでも1970年1月1日午前0時0分0秒から現在までの経過時間を1000分の1秒単位で取得し、ここからユーザーの cookie ファイルにある数字を引いて、もし 30000ミリ秒(30秒)以上経過しているか、或いはそもそも cookie ファイルに書き込みがなければ、 「不正なアクセスです」という警告ダイアログを出してから check.htm にジャンプさせる。

これはつまり、check.htm を通過せずに URL の直接入力で(或いは「お気に入り」や「ブックマーク」、「履歴」などで)secret.htm にアクセスしようとした場合、アクセスに失敗して check.htm に戻され、パスワードを要求されることを意味します。

30秒という数字は、ユーザーが「cookie を受け入れるときに警告する」の設定にしている場合、警告ダイアログの前で30秒近く考え込むことを考慮したもので、もっと短くしてもかまいません。またユーザーが「cookie を受け付けない」設定にしていた場合、cookie=="" ですから、これまたアクセスに失敗することになります。
アクセスに成功すれば document.write("・・・・")で JavaScript がこのページの内容を書き込みます。JavaScript のチェックを受けないマイナーブラウザでこのページの内容を見られなくするためです。

コンテンツのページがたくさんある場合には、それぞれの HTML ファイルに 上の secret.htm と同じスクリプトを書き、ただ (S-R) > 30000 ではなく、例えば (S-R) > 3600000 ぐらいにします。これは、check.htm を通過してから、1時間以内ならパスする、という意味で、アクセス時間制限にもなります。

ここにサンプルを作りました。下のボタンをクリックすると、パスワード入力ダイアログを表示します。パスワードは "Pghh4" です。試してみて下さい。


以上は、あくまで基本的なものであり、cookie によるチェックをもっと緻密にするとか、パスワードを暗号化するなどすれば、さらに良くなると思います。 いずれにせよ、これは JavaScript によるプログラムであり、JavaScript を読みとれないブラウザには使えない、という決定的な弱点があります。 もっと普遍的で、かつ万全のセキュリティを必要とするなら、基本認証や CGI によるチェックを使用した方がいいでしょう。

よくある質問

Q1: secret.htm の説明にあるelse document.write("(ページの内容を表すタグを書く)"); のやり方が判りません。

文字通り、HTML のタグを書き入れます。 例えば文章が長くなるときは、

else {
document.write("<DIV align='center'><TABLE><TR><TD>");
document.write("<A href='http://www.umechando.com/'>;梅ちゃん堂</A></TD>");
document.write("<TD>電脳レストハウス「梅ちゃん堂」</TD>");
document.write("<TR></TABLE></DIV>");
}

といった感じで適当な長さに切って繰り返し document.write するように します。

注意する点は、document.write("<DIV align='center'><TABLE><TR><TD>"); の例でわかるように、"..." で括っている中では引用符は "..." ではなく、 '...' を使うという点です。また各 document.write("..."); は1行で書くようにし、中に改行を入れないようにします。

Q2: JavaScript を使ったアクセス制限のよくある方法として、"(入力された文字)+.htm" の組み合わせがアクセス先ファイル名となるやり方があります。 これを上記の方法と組み合わせることは出来ませんか?

その場合は check.htm のスクリプトを

<SCRIPT Language="JavaScript">
<!--
result=prompt("パスワードを入れて下さい","");
if(result==null || result=="") location.href="index.html";
else
{
F=new Date();
S=F.getTime();
document.cookie="&chk="+S+"&end";
location.href=result+".htm";
}
//-->
</SCRIPT>

に書き換えます。「パスワードが違います!」のメッセージを表示することは出来ませんが、より安全性は増すでしょう。




次のトピックは「Image オブジェクトを使う」です。

目次 | ← 前のトピック | ↑ページのトップ | 次のトピック →

ご意見・ご質問がありましたら「ザ・掲示板」またはメールにて梅ちゃん堂まで