OmniAuth 是在 2011/11/2 正式釋出 v1.0 版的,其實也就是不久之前而已…
這個大改版也讓我吃足苦頭,因為 0.3 與 1.0 的架構差太多,網路上 Google 到的文件反而會打爆我的 application,除錯了很久。
不過也因為這件事情,逼我在幾個小時之內認真看了不少關於認證的想法與文件,才從而理解這些架構,寫出這些文章...。
0.3 與 1.0 的差異
0.3 與 1.0 的差異,在於 1.0 的架構更直覺、更乾淨。主要改變有二:
- Strategy as Gem
- 標準的資料介面
Strategy as Gem
在 0.3 版,如果開發者想在 Rails project 內使用 Twitter 的認證。除了必須在 Gemfile 內宣告使用 OmniAuth
還必須使用一個 initializer 去 claim 他要使用 Twitter 認證
而在 1.0 中
開發者只需要這樣作,在 Gemfile 裡面宣稱他要使用 OmniAuth 和 OmniAuth-Twitter
注意事項
其實也是這個細微的差異,害我誤入歧途,我按照網路上找到的方案,也在 1.0 版乖乖多寫了一個 initializer 去宣告使用,反而造成 invalid credential。
OAuth 惡夢
當然將 Strategy 抽出來當成 Gem 是一件好事,這樣就不用因為某一個認證方 API 改版,就必須 fork 整個 OmniAuth 出來使用。
不過促使 OmniAuth 改版最痛的問題可能是 OAuth 的問題。
我也是因為實作 Github 的認證才發現到這個令人憤怒的 issue。
[BTW: *講個不好笑的笑話,開發與 Github 結合的產品真的很令人困擾,因為你無法使用 "xxx github" 這樣的關鍵字在搜尋引擎找答案,因為結果一定會出現 xxx 在 Github 上的 repo。翻桌!=_=||| *]
這是 OmniAuth 0.3 版當時的 oa-oauth 目錄夾。你可以各家看到關於 OAuth 的認證實作多麼的混亂,逼得開發者只好寫出超多不同的 solution 去應對!
而 Github 雖然號稱已經支援 OAuth 2.0 (賀!?),但令人崩潰的是,它也不是標準的。Rails in Action 作者 Ryan Bigg 在寫作此本書範例程式的認證部分時,曾經憤怒的發現這一個事實,並把故事始末紀錄在這篇文章「Whodunit: Devise, OmniAuth, OAuth or GitHub?
」
OAuth 2.0 的規格說,token param 必須命名為 oauth_token,而 Github 的卻叫作 access_token。
而且 Github 不打算修這個問題…
所以如果在 0.3 版的 OmniAuth,你必須要 hack OAuth2 這個 gem 才能支援 Github...。而如果你同時要想支援 Facebook 認證,那就哭哭了 T_T
小結
而既然大家都這麼亂搞,不如把 Strategy 通通抽出來讓開發者在自己的黑箱內惡搞,可能還是比較快的一個方式....
標準的資料介面
在 OmniAuth 拿資料的方式是存取 env["omniauth.auth"]
這個變數,裡面會回傳認證需要的參數與資訊。
這個目錄 含蓋了所有目前 OmniAuth 0.3 支援的 Strategy,可以看到大家的 auth_hash 通通都寫的不一樣,也是各自為政。
所以在 1.0 版,OmniAuth 將強迫大家走同樣的規格回來,這些使用者資訊將會切成四種 DSL methods : info
, uid
, extra
, 和 credentials
。
這個部分在上一篇談架構時已經寫過,就不再重寫一遍了。
小結
經過這一番折騰,最後我還是成功用 OmniAuth 1.0 實作了 Github 認證。我將在下一節中示範如何整合。
但如果你還是想要用 0.3 實作 OmniAuth + Github 。我推薦你可以參考這篇 Stackoverflow 上的 GitHub OAuth using Devise + OmniAuth 討論。
Ryan Bigg 有個 ticketee 的 project 可以參考。(我不保證它能動)
Markus Proske 也有個 omniauth_pure 的 project 可以看。
Good Luck!