2011年9月13日火曜日

ディレクトリごとの設定ファイルを使う(.htaccessファイル)

Apacheを利用して、ユーザごとの公開ディレクトリを用意することができます。さらに、/home/user/public_html といったユーザの公開ディレクトリに対して、各々の設定をしたい。例えば、あるユーザの公開ディレクトリに対して、特定のディレクトリで SSI を有効にしたい、ということがあるでしょう。.htaccessファイルを使って実現することができます。

① Apacheの設定ファイル(httpd.con)から下のように ”AllowOverride All” を追加する
<Directory /home/*/public_html>
AllowOverride All
# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec                   
# <Limit GET POST OPTIONS>
# Order allow,deny
# Allow from all
# </Limit>
# <LimitExcept GET POST OPTIONS>
# Order deny,allow
# Deny from all
# </LimitExcept>
</Directory>

② Apacheの設定ファイルから、デフォルトの設定ファイル名(.htaccess)を確認しておく
AccessFileName .htaccess                           
 
③ 設定したいユーザ(hoge)の公開ディレクトリに移動して、設定ファイルを作成
[hoge@www~]$ cd ~/public_html/
[hoge@www public_html]$ vi .htaccess

④ .htaccessファイルに利用したい設定を記述する


しかし、AllowOverrideの設定を有効にする場合、サーバへの負荷が増加します。
そのことから、.htaccessファイルの使用は極力避けた方がよいです。
http://httpd.apache.org/docs/2.2/ja/howto/htaccess.html

Apacheの設定ファイルをいじれる(rootアクセス権限を持っている)のであれば、その設定ファイルに、設定を変更したいディレクトリを指定してあげるのがベストです。実際、.htaccessファイルに書くことで実現する設定は、Apacheの設定ファイルの<Directory> セクションを使って実現することができるし、その方が良い設定方法みたいです。

HTML::Templateを使って認証プログラムを作成

HTML::Templateを使用することで、外部に用意してあるHTMLをCGIスクリプトの中に読み込むことができます。HTMLデザインとスクリプトを明確に分離することで、メンテナンス性が高まります。ただし、HTML::Templateは標準モジュールではないので、CPANを使ってインストールする必要があります。

今回はHTML::Templateを使って、簡単な認証プログラムをかきました。
ID/PWに guest/guestと入力してログインボタンをクリックすれば、ログイン後のhtmlページを表示します。

%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%2525882011-09-1321.59.13-2011-09-13-21-05.png


enter.tmpl
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=shift_jis">           
</head>
<body>
<div align="center">
<form action="login.cgi" method="post">
<b>認証</b></br>
ID : <input type="text" name="id" ><br><br>
PW : <input type="password" name="pw" ><br><br> 

<div align="center">
<input type="submit" name="login" value="ログイン">
</div>
</form>
</body>
</html>

login.cgi
#!/usr/bin/perl

# モジュール宣言
use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use HTML::Template;

# ユーザのID/PW
my %user = ( "guest" => "guest" );

# CGIオブジェクトの生成
my $cgi = new CGI();

# ログイン処理
if ($cgi->param('login')) {       
        &login;
}
&enter_form;

#---------------------------------------------------------------------
# ログイン認証
sub login {
        # idのパラメータ取得
        my $id = $cgi->param('id');
        # pwのパラメータ取得
        my $pw = $cgi->param('pw');
       
        # id/pwがguest/guestならば、test.htmlを表示
        if ($id eq "guest" and $pw eq "guest") {
                print "Content-type: text/html\n";
                print "Location: ./test.html\n\n";
               
        }
}

# HTML::Templateを使用してログイン画面表示
sub enter_form {
        # HTML::Templateオブジェクトを作成
        my $tmpl = HTML::Template->new(filename => 'enter.tmpl');               
        # HTMLの出力
        print "Content-type: text/html\n\n";
        print $tmpl->output;
}        

今回は同ディレクトリに、HTMLテンプレートとCGIスクリプトを実装しましたが、テンプレートファイルはWebクライアントが直接アクセスできないディレクトリに配置するのが普通みたいです。

それと、CGIスクリプトの中にID/PWを記述するのではなく、隠しファイル等を使って、Webクライアントがアクセスできないディレクトリに配置しておかないとダメです。