What have you found for these years?

2011-11-20

rest-more (rest-core) 與 omniauth

對不起寫得很凌亂,其實我比較多只是希望寫下思緒而已... 當草稿也好。
不過這種東西大概幾年後也不會有多少價值就是了

*

omniauth 提供的是統一的 auth/login 方式,而 rest-more 則是提供有彈性
可任意使用 API 與 auth/login 的方式。因此使用 omniauth 可以很輕易地整合
使用者,但不能輕易地使用 API;反之 rest-more 不提供統一存取使用者的介面,
只提供容易操作各自 API 的方式,有比較大的彈性。

我們原本是用 omniauth, 因為看來看去我覺得是可以用的,一來他沒有做得很死,
一來他的程式寫得也沒有很糟,雖然我當時用的時候,連接 linkedin 的部分有嚴重的
bug, 甚至可以說是愚蠢的 bug (打錯字,還有一些格式錯誤),而且放很久一直沒有更新。

但隨著我們愈來愈需要有更細的 facebook 和 twitter 操作,使用 omniauth 來
認證會變得相當不方便。確切地說,就是 scope, permission 的設定變得不方便。
omniauth 在 rack middleware 上設定 scope, 但是我們希望是在 controller action
上設定,也就是不同 action 會有不同的設定!

稍微分析一下... omniauth:

* user 先連到 /auth/facebook 然後到 facebook 回到 /auth/facebook/callback
最後再回到 user 原本想去的地方。我個人覺得這是多餘的,不過用 rack 方式去做的話,
有可能不容易避免這件事。或是說,可能會把問題變得太過於複雜。

* 可以用統一的方式取得 user 資料

而 rest-more:

* 用 before_filter 來決定某個 action 要怎麼認證,流程是跑到 facebook 後,
可以直接回到原本的那頁。不過也是 facebook 提供 redirect_uri 才能這樣做,
像是 mixi 直接忽略這個參數,也就只能 redirect 回一個特定的頁面了..
那就變成跟 omniauth 一樣需要多 redirect 一次。

* 沒有統一存取 user 的方式,rest-more 也不會試圖去做這件事,一切取決於
各自的 API. 可以因此說 rest-more 是比 omniauth 要來得低階,只想做
thin wrapper.

再分析一下我們可能會使用到 auth/login 的時機:

* 我們希望 user 給予我們特定的資料,例如 facebook friends,
這種當然不可能期待 user 用 twitter login.

* 我們希望 user logs in, 無論是用哪種方法。而且我們「不在乎」
任何 login 方式間的差異。例如我們不需要 friends. 因此某種程度上,
我們也需要窮舉所有可以 login 的方式,也正是 omniauth 擅長的。

第二點要在 rest-more 中做,則同樣寫一個 auth controller,
並定義 facebook, twitter, etc, 然後每一個都給一個 before_filter,
依序用 rc_facebook_setup, rc_twitter_setup, respectively.
我不確定是否應該提供這樣的功能?總之我們這裡我是自己寫就是了。
畢竟 authorize 之後要做什麼事情,不同地方也會不同。

而第一點嘛,也理所當然就是 rest-more 的強項了...
混合 omniauth 與 rest-more 行嗎?我覺得如果還要用 RailsUtil 的話,
實在有點混亂。這也是為什麼我決定把 omniauth 全部拆掉了。

大概完成 95%, 剩下 twitter 的 rc_twitter_setup 還沒寫完。
貼一下之前寄給大家的筆記:

from: Lin Jen-Shin (godfat)
date: Thu, Nov 17, 2011 at 11:21 PM
subject: auth and user revisited note

This is a development mlog (or elog, parody of weblog) :P
You can read it as an FYI. I am just trying to write down
my thoughts to see if what I am thinking is correct or not,
instead of jumping through the codes.

So basically we would have two use cases.

* We want people to authorize with a specific web service.
For example, we want to show facebook photos of a user,
but not twitter photos, since there's no such thing on twitter.

* We want people to authorize to us with any web service,
either twitter or facebook. Currently, the only place we're
using this is in /admin.

Previously, we're using `current_user` to get the user who
is visiting the page. I think we should remove it, in favor of
`current_auth`, because everything begins with a auth (
e.g. facebook or twitter) but not a user!

Summary:

* use `current_auth.user` to get the current user

* use `bb_facebook_setup` to setup facebook access,
which is a wrapper around rc_facebook_setup

* use `bb_twitter_setup` to setup twitter access,
which is a wrapper around rc_twitter_setup

* use `filter_try_login` for pages we don't care which
web service the user would want to login with,
and the user could choose to not to login.

* use `filter_enforce_login` for pages we want to
user to login with arbitrary web service (including
our own login system!)

Ok, now I am thinking how to implement them correctly.
Stay tuned! (?)

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0