Categories
open all | close allTags
Aptana | 認証 | スキンエンジン | rake | 国際化 | フォーム | デュアル・コア | Migration | Subversion | テスト | Flash | RESTful | パソコン | 名称 | ドキュメント | CSRF | モデル | アクセス制御 | タグ | OpenIDSearch
認証の部分
アイテムでのprevlink,nextlinkもできました。ということで,スキン変数,テンプレート変数で実装していないのはまだまだたくさんありますが,次のフェーズに移ることを優先したいと思います。最近,コードを全く紹介していなかったので,現状の認証用コードをあげておきます。
def setmember
if (params['memberid'])
result = htpasswd_authorize
if @htpasswd_authorized_username
if params['memberid'] == ''
redirect_to(:controller=>'members', :memberid=>@htpasswd_authorized_username, \
:action=>'show')
else
if @htpasswd_authorized_username != params['memberid']
redirect_to(:memberid=>'', :action=>'show')
end
end
@member = Member.find_by_mname(@htpasswd_authorized_username)
end
return result
end
return true
end
これをbefore_filterで動かしています。つまりURLでmemberidが設定されたとき(/member/だけでも空文字列を設定するようにしています)だけ認証を行います。後はhtpasswdプラグインをちょっといじって,そちらでのbefore_filterを止めているのと,Nucleusのmemberテーブルに入っているMD5で暗号化されたパスワードとマッチするようにしています。
認証に成功した場合はコントローラの@member変数にメンバーのオブジェクトが入ります。
ページング処理を追加
といってもShowBlogsみたいな完全なページリンクではなく,従来からのprevlink,nextlinkに対応しただけです。link_toがヘルパーでしか使えないことに気付かず,思ったより時間がかかってしまいましたが,それ以外は特に問題なく。もともとモデルからアイテムを引っ張ってくるメソッドにオフセットを入れていたので,そこのパラメータを変えるだけで簡単にできました。というわけでpaginating_findを一応インストールしてみたものの,今のところは出番なく。このまま出番なしでいくのか,ページングの高機能化をするときに使うのかは保留状態です。
ところでprevlinkやnextlinkはアイテムページでも使えるわけですが,ここのサポートって結構難しいかも。そのときのコンテキストに依存するため,ちゃんと条件を与えて前や後のアイテムを調べないといけません。まあしょうがないからついでに考えておきましょう。
それから,ページングを高機能化する場合,カスタマイズ性をどうやって担保するのかって問題がでてきます。スキン変数を新たに作って好きなようにしてもらうのか,あるいは決めうちで作ってCSSでなんとかしてもらうのか。設計からすると前者の方法でやりたいところです。
02 Mar, 2008 | Foodyn ( 実装メモ , つぶやき , 作業メモ ) | ページネーション / prevlink / nextlink | Andy | Leave comment - 2 -
認証の処理
現在の仕様では,memberで始まるパスにアクセスするときだけ認証をかけることにしています。例えばコメントフォームに登録ユーザーと同じ名前でコメントする場合,memberのパスにリダイレクトしてから処理する予定です。認証にはHtpasswdプラグインを使います(こちらとこちらを参照)。ダイジェスト認証も使えるからです。
このプラグイン,コントローラ単位で認証をかける仕様になっています。気持ちとしてはメソッドで認証の必要があるかどうかを判定して認証するようにしたかったのですが,試した範囲では難しそう。しょうがないので,membersのコントローラだけ認証をかけるようにして,認証に通ったらrender_componentを使って他のコントローラに制御を引き渡して描画させるようにしました。こうするとコントローラの中でパラメータを判定して引き渡し先を選ばないといけないのでDRYの原則から大きくはずれてしまうのですが,ほかにうまい方法が見つかっていないので,現状はそうしています。
まだ今のmemberテーブルの内容とどうすり合わせるか,決めていませんが,基本的に上記の枠組みで動くことは確認できました。
PS. 思いつきですが,認証後にその情報をセッションに入れてmemberなしのパスにリダイレクトするといった方法もあるかもしれません。セッション・ハイジャックなどの危険性がやや気になるところではありますが,DRYにはなります。
やっとコメント機能を実装
普通にRailsの機能を使ってフォームからAcrive Recordのオブジェクトを作って保存しているだけ(まだエラーチェックもスクリプトインサーション対策も何もしていません)なのですが,CSRF対策機能以外にも2点ほど引っかかってけっこう時間を食ってしまいました。まあ更新系は初めてなので多少ひっかかるのはしょうがないかもしれません。引っかかったところの一つ目は
def create
@comment = Comment.new(params[:comment])
respond_to do |format|
if @comment.save
format.html { redirect_to(params[:destination]) }
else
format.html { render :action => "new" }
end
end
end
の最初でフォームのパラメータからCommentオブジェクトを作るところ。フォームからデータは来ているのに設定されないインスタンス変数がいくつかありました。実はこのあたりの機能は諸刃の剣のところがあって,簡単に処理できる反面,フォームを偽装されると意図していないフィールドまで書き換えられてしまうセキュリティホールを作ってしまう可能性があります。Railsにはそれを防止する機能もあるのですがどうやらそれが働いてしまっているような感じがしました。Commentクラスでは,どうしてそうしたかは覚えていないのですが,attr_accessorを使っていくつかのフィールドを読み書き可能設定しています(Active Recordではこれをやらなくても読み書きできます)。試しにこれをはずしてみたら動くようになりました。
二つ目にはまったのはもっと単純。保存時にエラーが出るようなので,データの問題かと思っていろいろ調べてみたのですが,結局はエラーをちゃんと見ていなかっただけ。保存時の問題ではなく保存後にリダイレクトするURLを生成する部分の問題でした。ここはフォームから渡されるdestinationを使って解決。
ちょっと時間かかりすぎですね。
やっと前進
RESTのrespond_toのところだけ使う方法というのが分からずに苦労していたわけですが,本屋で「RailsによるアジャイルWebアプリケーション開発 第2版」のRESTのところを立ち読みしてみたら,書いてありました。あー,やっぱりこの本も必要かなあ…。高いのと厚いので敬遠していたのですが(ちなみに第1版は読みました)。RailsによるアジャイルWebアプリケーション開発 第2版
Dave Thomas、David Heinemeier Hansson、Leon Breedt、Mike Clark、Andreas Schwarz、James Duncan Davidson、Justin Gehtland、前田 修吾
オーム社
2007/10/26
¥ 4,410 (定価)
¥ 4,410 (Amazon価格)
44pt (Amazonポイント)
(私のおすすめ度)
★★★★★ (Amazonおすすめ度)
大型本
通常24時間以内に発送
(価格・在庫状況は8月29日 2:21現在)
Dave Thomas、David Heinemeier Hansson、Leon Breedt、Mike Clark、Andreas Schwarz、James Duncan Davidson、Justin Gehtland、前田 修吾
オーム社
2007/10/26
¥ 4,410 (定価)
¥ 4,410 (Amazon価格)
44pt (Amazonポイント)
(私のおすすめ度)
★★★★★ (Amazonおすすめ度)
大型本
通常24時間以内に発送
(価格・在庫状況は8月29日 2:21現在)
具体的にどうするかというとルーティングのところ,例えばアイテムページは
map.item 'item/:itemid', :controller => 'application', :action => 'item'
といった形になっていたわけですが,まずこれを
map.item 'item/:id', :controller => 'items', :action => 'show'
といったRESTのスタイルのコントローラとアクションに書き換えます。
そして,フォーマットの拡張子に対応するために
map.item 'item/:id.:format', :controller => 'items', :action => 'show'
というのを付け加えます。これで,REST対応のscaffoldが生成したItemsControllerのshowメソッドで受けられるようになります。後は
def show
@item = Item.find(params[:id])
respond_to do |format|
format.html { item }
format.xml { render :xml => @item }
end
end
といった形でHTML形式が要求されたときはitemメソッド(今のところ従来のままApplicationControllerにあります)で表示します。
標準でlayoutファイルが使われることに気付かず,しばらく悩みましたが,ようやくこれでアイテム・ページを表示できるようになりました。拡張子.xmlを付けたらXMLでも表示できました。後はこれにならってルーティングとコントローラ周りを修正すれば,RESTのスタイルになります。
結局表示のREST対応を考えるだけで1ヶ月近くかかってしまいました。このあたりはあまり情報が多くないので苦労します。
RESTでRest
Rails2.0についての開発者のブログを読んでいたら,RESTについて強調しているので,あらためて勉強,っていうか知らなかったですよ,REST。今のところGETを使う閲覧系しか実装していないから1.2の上でもRESTにはできるはず。将来を考えたらやっぱりそうするべきなんでしょうねえ,と思ってちょっとそちらを調べています。ということで今日もコードはなし。ちょっと休憩(rest)。
日本語の資料ではここが一番役に立つのかな。これの原文の英語版はこちら(PDF)。
RESTなアーキテクチャにするにはクッキーにユーザー情報を格納しておくというのはまずいため,のびのびになっている認証にもまた絡んできます。BASIC認証は使っていいよという話もありますが,ブログの場合はログインしていないユーザーにも閲覧できるようにする必要があるためBASIC認証とはちょっと相性がよくなさそう。それともログインが必要なURLにはユーザーIDを入れてしまうとか? なんだかかえって使い勝手を落としてしまいそうな気もします。
使うのをあきらめたacts_as_authenticatedの派生プラグインでrestful_authenticationというのもあるようですが。どうしましょうかねえ。
acts_as_authenticatedを統合するのは難しい
いろいろ調べた結果(ここが一番参考になりました),acts_as_authenticatedを認証機能として組み込もうとしたのですが,かなり面倒です。既存のNucleusからの移行性をどこまで持たせるかという問題があり,member情報をそのまま引き継ごうとすると,(当たり前ですが)acts_as_authenticatedでは認証できません。
後々の手間を考えると,認証はなるべく軽く,最終的にはここもプラガブルにしたいのですが,今のNucleusの認証を移植する方が結局手間が少なくてすみそうです。
一番いいのは当面Nucleusの認証で運用しておき,ユーザーに自分でバージョン・アップさせて別の認証に置き換えるといった形ですが,ちょっと自分の手には余る感じです。
認証に寄り道をしようかと思う
コメント更新を実装するつもりだったのですが,セッション管理とかしたほうがいいのかなあなどと考えつつ,それだったら先に認証を作っておかないといけないのかなあと,寄り道というか当初はその予定だったのですが,認証系を調べ始めています。プラグインがたくさんで理解するのが大変。acts_as_authenticatedというのがかなり使われているっぽいのですが,もう1つ機能がよく分かっていません。before_filterでチェックするのでしょうけど,ログインを強制されるようだと困ってしまいます。ブログの場合は「名無し」のユーザーもいるわけだから。そういった使い方ができるのかどうかがまだ見えていません(要は何もわかっていない)。とりあえずプラグインのインストールだけしてしまいましたが,後はどうしようって感じです。
