本文用的 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:
[code lang=”ruby”]
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
…
[/code]
因為 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 來處理驗證完畢的確認:
[code lang=”ruby”]
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
[/code]
簡單地說,在驗證的時候是用 OpenID consumer 的begin
,在確認這個步驟時是用complete
,最後再檢查response.status
的 status code 就可以判斷 OpenID 的驗證是否成功了。
因為最近比較沒空,我就沒有把這樣的動作整合到 acts_as_authenticated 這個 plugin 裡面了,有興趣的人可以試著去做做看 😛
1 comment
Comments are closed.