MTでログインユーザー限定のページを作る方法。
公開日 : 2007-09-13 19:47:20
ログインユーザーだけがページを見られるようにしたいってニーズは結構あるようなので。一例を紹介してみる。
考え方
ダイナミック・パブリッシングであればページを生成してリプライするプログラムの中でログインの有無を設定してやれば良い。静的生成の場合はどうするか?
- MTのクッキーの有効範囲をサイト全体にする
- 生成されるファイルの名前の後ろに(例えば) .deny を付けるようにする (アーカイブ・マッピングの設定でも良いし、build_file コールバックに対応したプラグインを書いても良い
- ユーザー限定ページのディレクトリに対するApacheの設定で.denyへのアクセスを拒否する
- ユーザー限定ページのディレクトリに対するApacheの設定でmod_rewrite又はNotFoundの設定によってリクエストがプログラムに渡るようにしておく
- プログラムの中でログインの有無をチェックするようにする
- 例えば example.html ページが存在しない場合、ログインユーザで且つ example.html.deny が存在すれば example.html.deny の中身を返す
以下、MTが /mt以下に、/authディレクトリ以下をログインユーザー限定ページにしたい場合(ファイルのリネームのところは省略します。build_fileコールバックが呼ばれた時に /authディレクトリ以下だったら.denyを付けてリネームするプラグインを書けば良い)。
/mt/mt-config.cgi
CookiePath /
/auth/.htaccess
<Files ~ "¥.(deny)$">
Order allow,deny
Deny from all
</Files>
Options -Indexes +SymLinksIfOwnerMatch
<IfModule mod_rewrite.c>
<IfModule mod_dir.c>
DirectoryIndex index.php index.html index.htm default.htm default.html default.asp
</IfModule>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /mt/plugins/SimpleAuth/SimpleAuth.cgi [L,QSA]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /mt/plugins/SimpleAuth/SimpleAuth.cgi
ErrorDocument 403 /mt/plugins/SimpleAuth/SimpleAuth.cgi
</IfModule>
/mt/plugins/SimpleAuth/SimpleAuth.cgi
#!/usr/bin/perl -w
use strict;
use lib 'lib';
use lib '../../lib';
use lib '../../extlib';
use MT::Bootstrap App => 'SimpleAuth';
/mt/plugins/SimpleAuth/lib/SimpleAuth.pm
package SimpleAuth;
use strict;
use MT::App;
@SimpleAuth::ISA = qw(MT::App);
sub init_request {
my $app = shift;
$app->SUPER::init_request(@_);
$app->add_methods( auth => ¥&_auth );
$app->{default_mode} = 'unprotected';
$app->{requires_login} = 1 unless $app->mode eq 'unprotected';
$app->add_methods( unprotected => ¥&_unprotected );
$app;
}
##############################################################################
#Setting
my $base = '/Applications/MAMP/mt4local2';
my $suffix = '.deny';
##############################################################################
sub _unprotected {
my $app = shift;
my $login = $app->login;
if (defined $login) {
return &_auth($app);
} else {
$app->set_header('Status','401 Unauthorized');
return 'Requires Login.';
}
}
sub _auth {
my $app = shift;
my $path = $app->param('path') || $ENV{"REDIRECT_URL"};
$path =~ s/¥.¥.//g;
my $file = $base.$path.$suffix;
if (-f $file) {
open(FH, $file) or die;
my @data = <FH>;
#$app->set_header('status', 200);
$app->send_http_header();
$app->print(@data);
} else {
$app->set_header('Status','404 File Not Found');
return 'File Not Found.';
}
}
1;
html以外のファイルを処理する場合は拡張子からContent-Typeを識別して付与してやるとか、ディレクトリへのアクセスだったら /index.html を探すようにするとか、そのあたりの処理は必要ですが、基本的にはこんな感じ。