本文用的 ruby-openid 是 2.0.4 版本,目前的 acts_as_authenticated plugin 只有整合到 ruby-openid 1.1.4 版本。
OpenID 的介紹在之前的文章就已經寫過了,這篇文章主要是記錄一下我在 Rails 上使用 ruby-openid 這個 gem 整合 OpenID 的過程。以下就以 step by step 的方式作介紹:
- 安裝 ruby-openid 這個 gem:
gem install ruby-openid - 在負責處理登入驗證的 controller 中,加入
auth_by_openid這個 action:require 'openid' require 'openid/store/filesystem' ... def auth_by_openid(openid) @@store ||= OpenID::Store::Filesystem.new("#{RAILS_ROOT}/tmp/_openid") begin c = OpenID::Consumer.new(session, @@store) req = c.begin(openid) if req.nil? flash[:error] = "Open ID fail" redirect_to_signin else redirect_to req.redirect_url("", url_for(:action => "confirm", :controller => "account")) end rescue OpenID::DiscoveryFailure flash[:error] = "OpenID 格式錯誤" redirect_to_signin end end ...
因為 OpenID 的認證必須要有地方存著 session 資料,目前的 ruby-openid 有提供一個儲存在 file system 的 module,所以
@@store就是用來表示儲存 session 的物件。接著用
OpenID::Consumer來操作 OpenID consumer 的動作,begin這個 method 會去 OpenID server 詢問一下傳入的 OpenID 是哪個單位的,如果成功,則會把要導向的 URL 記在回傳值中,所以我們必須用redirect_to把 user 導向它 OpenID 驗證的頁面去作帳號密碼驗證。而
req.redirect_url第一個參數應該是「認證過的網站」的一個代碼,如果你的網站沒有被 OpenID 認證過,這裡可以代長度為0的字串,而第二個參數則是:當 OpenID 認證完畢後,要導回到你網站的哪個位置,所以我們還要再用一個 action 來處理 OpenID 認證完的結果。因為用戶可能輸入的不是合法的 OpenID,所以要處理 OpenID::DiscoveryFailure 這個 exception。
- 根據上述的步驟,還要再定義一個 action 來處理驗證完畢的確認:
def confirm @@store ||= OpenID::Store::Filesystem.new("#{RAILS_ROOT}/tmp/_openid") c = OpenID::Consumer.new(session, @@store) response = c.complete(params.reject{|k,v|request.path_parameters[k]}, url_for(:action => "confirm", :controller => "account")) if response.status == OpenID::Consumer::SUCCESS # 成功 else # 失敗 end end
簡單地說,在驗證的時候是用 OpenID consumer 的
begin,在確認這個步驟時是用complete,最後再檢查response.status的 status code 就可以判斷 OpenID 的驗證是否成功了。
因為最近比較沒空,我就沒有把這樣的動作整合到 acts_as_authenticated 這個 plugin 裡面了,有興趣的人可以試著去做做看 :P
歷史上的今天
- 自己做麻婆豆腐 - 2007

0 Response to “在 Rails project 上導入 OpenID”