Skip to main content

10分鐘理解OAuth和facebook登入原理

Opass
A life well lived

最近接了一個要求使用facebook做登入的案子,因此花了好些時間研究facebook登入如何實作。決定留下紀錄,供日後步上相同道路的人參考。

首先,要先理解OAuth是拿來做什麼的,才能知道如何利用他。常聽到OAuth和OpenID,最簡單的說法就是

OpenID:用作「身份認證」,如果某網站support OpenID,你登入其他網站不需要記憶密碼,只要拿你的OpenID登入就好。

OAuth:用作「授權」,舉例而言,如果你需要授權某相片列印公司的網站取得你在Facebook的相片,只要該相片列印公司support OAuth,你也授權,那該公司就可以取得你在Facebook的相片。

今天不談OpenID(因為我也還沒研究),只談OAuth。直接講重點,究竟OAuth要怎麼進行授權?

OAuth有分1.0和2.0,我們只討論比較新的2.0

首先,分四個角色

  • 資源擁有者(Resource Owner): 可以想成擁有Facebook帳號的小明。
  • 授權伺服器(Authorization Server): 相片列印公司向facebook取得使用者授權的伺服器
  • 資源伺服器(Resource Server): 保管你facebook相片的server
  • 用戶端(Client): 想要取得你facebook相片的列印公司

整體的流程是:

首先,相片列印公司在facebook有一個應用程式。

有一天,小明想要到哇哈哈相片列印公司網站想要列印自己的生日Party照片,哇哈哈必須要取得小明的facebook帳號授權,才可以取得小明在facebook的照片。

因此哇哈哈會把小明重新導向到facebook,小明必須向facebook說明「我授權給哇哈哈相片列印公司」,之後facebook會告訴哇哈哈的網站「我已經取得小明的授權了」,證明的方法是發送一個授權token給哇哈哈的網站。

但這時哇哈哈不能確定這個授權token真的是facebook給的,可能是某個不懷好意的無聊資工系學生(相信我,這種人很多)對你的網站進行練習資訊安全作業惡搞你。因此哇哈哈必須要把這個token送回給facebook,讓facebook告訴哇哈哈這個授權是真的,如果是真的,facebook會交給哇哈哈一串「access_token」,這個東西就是萬能的鑰匙!哇哈哈公司用這個就可以向facebook取得所有小明授權的資料了!

facebook並沒有提供OpenID服務,只提供OAuth,因此雖然OAuth的用途不是身份認證,但我們可以利用OAuth的特性來登入使用者。

接下來我們直接來看facebook文件吧。

facebook登入有分JavaScript登入,由Facebook提供SDK,都幫你包好了。或者你可以手動自己刻Server Login。但說真的,雖然我有用過Facebook JavaScript Login,但原理我沒有很清楚,一下子就突然登進去。所有取得授權資料code都是javascript,不過直接把程式碼暴露在前端還是怕怕的,如果對安全性比較要求的話還是自己慢慢刻後端登入吧。

手動登入Facebook官方文件

接下來請一邊參考官方文件,一邊參閱我的解釋,這樣學習的效果最好。

首先,你必須在Facebook建立一個應用程式。建立完後啟動網站登入功能,會得到

Selection_003

首先,你的網站必須把使用者重新導向回facebook,讓使用者告訴facebook可以授權給你。

因此建立一個取得授權的連結如下:

Selection_004

client_id當然就填你的應用程式ID, redirect_uri填入facebook授權完之後,要告訴你網站的哪個網址。其他還有一些參數可以設定自己看文件啦。

如果授權成功, facebook會向你給的redirect_uri傳一串code給你,這個code就是使用者授權給你家網站的證據。但問題是,你不能確定這個code真的是facebook傳回給你的,老樣子,網路是很危險的。

因此你必須要拿這個code向facebook換access_token

Selection_005

因此,請自行在後端向facebook發出這個請求,記得填入你的app-id和app_screte key, 如此一來才能向facebook證明你就是這個應用程式的擁有者。之後facebook等待facebook的response。記得,這裡的redirect_uri必須要和上面的取得授權的uri相同,不然facebook會覺得你這個人怪怪的。

之後如果驗證成功,facebook會response你一個access_toke,這個就是你費盡千辛萬苦終於得到的facebook鑰匙,憑此就可以到授權給你的人的facebook相簿拿取他的相片了。如果錯誤的話,facebook會回傳你一段json格式的錯誤訊息。但正確的話,會回傳給你一串

Selection_006

字樣,上面還會寫expires time(單位是秒), 要盡早使用,不然會過期。

取得access_token之後,請保存好,這就是這個人的授權鑰匙,你可以拿這個access_token去問facebook這個人是誰,facebook就會告訴你,因此你就把該名使用者資訊寫到database註冊這名使用者。

利用access_token 取得資訊的方法請參閱官方文件 使用facebook graph api,建議可以利用graph explorer玩一玩,就可以知道利用access_token換取使用者資料。

同樣的,之後該名使用者如果再度來到你的網站,你一樣可以問facebook該名使用者是誰,然後檢查是否資料庫已經存在該名使用者的資料,如果是的話,就可以把該名使用者登入進去你的網站。

以上,就是嘗試對facebook OAuth做簡單的說明,旨在讓不熟悉的人能快速了解整個facebook手動登入的全貌,如果有錯誤歡迎大家批評指教留言更正。

參考資料: