はてな認証APIかフォーム認証で tDiary にログイン
2006-06-18
先月末に公開した tDiary の認証プラグイン (厳密にはコアを拡張しているのでプラグインじゃない) に手を加えて、 HTML フォームでも認証できるようにした。 先日の Ruby カンファレンスでも、 Basic 認証以外に対応しないんですか?って質問が出ていたしね。
極力、コアに手を入れないように作ってみたけど、どうだろう。
できること
- はてな認証API を使ったログイン
- HTML フォームを使ったログイン (ID/パスワード認証)
- ゲストユーザと管理ユーザの区別 (管理ユーザのみ日記の編集を許可)
まだできないこと
- ゲストユーザだけにツッコミを許可する
- 設定画面からのユーザ管理
- 設定画面からの初期設定
サンプル
サンプルを設置しました。管理者ユーザでログインして日記を編集できます。
http://www.machu.jp/sample/tdiary-auth/
ダウンロード
最新開発版の tDiary (2.1.4) が必要です。
- http://www.machu.jp/dist/tdiary_auth-20060618 (ソースだけ見たい人向け)
- http://www.machu.jp/dist/tdiary_auth-20060618.tar.gz (上記のアーカイブ)
インストール
アーカイブを展開すると、以下のファイルが生成されます。
index.rb
update.rb
tdiary.conf.auth
tdiary/auth.rb
tdiary/auth_hatena.rb
tdiary/auth_form.rb
plugin/03auth.rb
skel/login.rhtml
misc/mkpasswd.rb
これらのファイルを、最新開発版の tDiary (2.1.4) に上書きしてください。 次に、 tdiary.conf.auth を参考にして tdiary.conf を編集します。
@options['author'] = ['admin']
@options['form_auth'] = {
'guest' => '49327:c028285dd70368dbf061bd47ddf9c9dd',
'admin' => '859091:6f9ea824fe1549fe502ce62f0e64d582',
}
# require 'tdiary/auth_hatena.rb'
# @auth_class = TDiary::AuthHatena
@options['hatena_auth'] = {
:api_key => 'input your api_key',
:secret => 'input your secret'
}
@options[‘form_auth’] は HTML フォーム認証用の設定です。 ユーザ名とパスワードの対で構成されています。 パスワードは salt と生パスワードのハッシュ値を : で連結したものです。 パスワードのフォーマットを Ruby で表現するとこのようになります。
digest = Digest::MD5.hexdigest(salt + plain)
"#{salt}:#{digest}"
misc/mkpassrd.rb を使うと、簡単にパスワードフォーマットを生成できます。
@options[‘hatena_auth’] ははてな認証 API を使うための設定です。 設定ファイルにははてな認証 API のページで取得した API キーと秘密鍵を設定してください。 また、はてな認証 API のページで設定するコールバック URL には、あなたの日記のトップページの URL を設定してください。
@options[‘author’] は管理者ユーザ (日記の編集を許可するユーザ) を記述します。 はてな認証 API を使う場合は、はてなユーザ名の後ろに @hatena.ne.jp を付けて下さい。
新しい認証方式への対応
認証部分は別クラスに分離しているので、 TypeKey や OpenID への対応も容易にできると思います。
- 認証クラス (例, AuthTypeKey) を作り、 tdiary/autn_typekey.rb として配置する
- tdiary.conf に以下の設定を記述する。
require 'tdiary/auth_typekey.rb'
@auth_class = TDiary::AuthTypeKey
参考
index.rb と update.rb への差分は以下のとおり。 TDiaryLogin への分岐を追加しているだけ。
Index: update.rb
==================================================================
--- update.rb (revision 2679)
+++ update.rb (working copy)
@@ -16,13 +16,16 @@
end
$:.unshift( org_path.untaint )
require 'tdiary'
+ require 'tdiary/auth'
@cgi = CGI::new
conf = TDiary::Config::new(@cgi)
tdiary = nil
begin
- if @cgi.valid?( 'append' )
+ if !conf.session
+ tdiary = TDiary::TDiaryLogin::new( @cgi, 'login.rhtml', conf )
+ elsif @cgi.valid?( 'append' )
tdiary = TDiary::TDiaryAppend::new( @cgi, 'show.rhtml', conf )
elsif @cgi.valid?( 'edit' )
tdiary = TDiary::TDiaryEdit::new( @cgi, 'update.rhtml', conf )
Index: index.rb
===================================================================
--- index.rb (revision 2679)
+++ index.rb (working copy)
@@ -16,6 +16,7 @@
end
$:.unshift( org_path.untaint )
require 'tdiary'
+ require 'tdiary/auth'
@cgi = CGI::new
conf = TDiary::Config::new(@cgi)
@@ -27,7 +28,11 @@
end
begin
- if @cgi.valid?( 'comment' ) then
+ if @cgi.valid?( 'login' ) then
+ tdiary = TDiary::TDiaryLogin::new( @cgi, "login.rhtml", conf )
+ elsif @cgi.valid?( 'logout' ) then
+ tdiary = TDiary::TDiaryLogout::new( @cgi, "logout.rhtml", conf )
+ elsif @cgi.valid?( 'comment' ) then
tdiary = TDiary::TDiaryComment::new( @cgi, "day.rhtml", conf )
elsif @cgi.valid?( 'date' )
date = @cgi.params['date'][0]
ToDo
自分用のメモです…。
ログインするまでセッション Cookie を発行しない- はてな認証APIへのリクエスト生成時に無条件で全てのパラメータに署名している
- 日記の編集画面がクライアントのキャッシュに残る
- HTML 認証でログイン失敗時にエラーメッセージが表示されない