はてな認証APIかフォーム認証で tDiary にログイン
先月末に公開した 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 認証でログイン失敗時にエラーメッセージが表示されない