各大網站 OAuth 2.0 實作差異

因為我現在要自己做 OAuth 2 的服務,所以當然要先看一下別人怎麼做。

然而,即使 OAuth 2.0 的 spec 規定了很多通訊協定上的實作細節,但現實總是跟理想有所差距,各大網站的 OAuth 2 實作都或多或少與 spec 有差異,真正完全照 spec 來做的很少(功能閹割的不算數)。不過概念上都符合 OAuth 2 ,只是實作上有差。

我去看了以下這些網站的 OAuth 2 API 文件,清單是從 Wikipedia / OAuth / List of OAuth service providers 找來的。為了排版美觀, Grant Type 的 Authorization Code 簡寫成 Auth Code, Client Credentials 簡寫成 Client Cred.,Resource Owner Password 簡寫成 Password。檢閱日期是 2013 年 9 月 27 日,未來各 API 可能會改變,導致下表的情況跟現況不一致。

Service spec
相容
支援的 Grant Types scope
分隔
Refresh
Token
Client 認證
Facebook Auth Code, Implicit, Client Cred. comma △ (自製) GET
GitHub Auth Code, Password (自製) comma POST
Twitter Client Cred. (無 scope) Basic
Google Auth Code, Implicit space POST
Microsoft Auth Code, Implicit ??? POST
Dropbox Auth Code, Implicit (無 scope) Basic, POST
Amazon Auth Code, Implicit space Basic, POST
Bitly Auth Code (半自製), Password (無 scope) POST (Auth Code),
Basic (Password)
新浪微博 Auth Code comma Basic, GET
豆瓣 Auth Code, Implicit comma POST
BOX Auth Code (無 scope) POST
Basecamp Auth Code (無 scope) POST

大概總結一下:

關於 Endpoints:

關於 Grant Types:

關於 Client Authorization (認證):

關於資料格式:

其他:

以下各服務的筆記。

Facebook

文件: https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/

Grant Types

Endpoints

特色

其他值得參考的文件:

關於固定的 Redirection URI

前面提到說它的 Redirection URI 固定為 https://www.facebook.com/connect/login_success.html ,這個 URI 我覺得很有意思,打開來是這樣的內容:(斷行是我自己加的,原文沒斷行)

Success <br /><b style="color:red">安全警告:請以保護密碼的相同態度處理以上網址,切勿和任何人分享。</b>
<script type="text/javascript">
setTimeout(function() {
  window.history.replaceState && window.history.replaceState({}, "", "blank.html#_=_");
},500);
</script>

看這段 JavaScript,用途是「500ms 之後自動把瀏覽器的歷史記錄消滅掉,並且讓現在網址變成 blank.html#_=_」。這是什麼用途呢?

我猜測搭配 Implicit Grant Flow 用的。在 Implicit Grant Flow 裡面, Access Token 會包在 Fragment 裡面(就是網址最後面的那個 #xxxx),這樣子一來會被 User-Agent 放進歷史記錄裡,二來如果人眼看得到這個 User-Agent 的 Location Bar ,就可以看到 Access Token 。

所以 Facebook 推薦給 Desktop App 的實作方式,就是程式監視內嵌的 User-Agent 的當前網址,看到這個固定的 Redirection URI ,就可以抓 Access Token 了。而不管有沒有抓到,網頁裡的 script 都會把 Access Toekn 消除掉。

又,這種 #_=_ 也常常在 Facebook 第三方登入的時候看到,我猜測也是基於相同的原因,不過還沒有證實。

GitHub

文件: http://developer.github.com/v3/oauth/

Grant Types

Endpoints

用於 Authorization Code:

Resource Owner Password Grant Flow 是自製的流程,叫做 Authorizations,用的是 RESTful API,不是直接套用 OAuth 標準。在 Grant 的時候不使用上述的 Endpoints。

特色

GitHub.app 即是使用 OAuth

GitHub 的 Mac GUI 應用程式就是用 OAuth 來存取資料的。你可以打開 Keychain Access ,找到 "github.com/mac (you@example.com)" 這個項目,按 Show Password 就可以看到 OAuth Access Token 了:

![Screen Shot 2013-09-30 at 2.46.03 PM.png](https://pub-e523589e504d4ca49336e74978c38e52.r2.dev/images/2013/2013-09-30-oauth2-implementation-differences-among-famous-sites/xQ9h86TQDmXKQB5CKT7T_Screen Shot 2013-09-30 at 2.46.03 PM.png)

用同樣的 Access Token 可以 call API:

$ curl -i -H "Authorization: token bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXb" https://api.github.com/user
HTTP/1.1 200 OK
Server: GitHub.com
X-OAuth-Scopes: notifications, repo, user
X-Accepted-OAuth-Scopes: user, user:email, user:follow, site_admin
X-GitHub-Media-Type: github.beta
X-Content-Type-Options: nosniff
# 部份略

{
    "login": "chitsaou",
    "id": 10737
    (略)
}

Twitter

文件: https://dev.twitter.com/docs/auth/application-only-auth

Grant Types

Endpoints

特色

Google

文件: https://developers.google.com/accounts/docs/OAuth2

Grant Types

還有一種 Grant Flow 叫做 "for Devices" ,這是專門為 User-Agent 功能很少的設備來設計的,例如遊戲機、印表機。

Endpoints

特色

Microsoft (Windows Live)

文件: http://msdn.microsoft.com/en-us/library/live/hh243647.aspx

Grant Types

Endpoints

特色

Dropbox

文件: https://www.dropbox.com/developers/core/docs

Grant Types

Endpoints

特色

Amazon

文件: http://login.amazon.com/website 裡面的一份 PDF

Grant Types

Endpoints

特色

另外文件裡面還提到安全性問題 (Security Considerations),是從 Spec 的 Security Considerations 來的,但比 spec 的好讀……。

其中我特別注意到的幾點:

Bit.ly

文件: http://dev.bitly.com/authentication.html

Grant Types

Endpoints

特色

Bit.ly 的情況比較特別,它雖然有 Authorization Code Grant Flow ,但實作的細節卻跟 OAuth 2.0 有點不同,這個不同就導致它與 spec 不相容:

其他特色:

新浪微博

文件: http://open.weibo.com/wiki/授权机制说明

Grant Types

Endpoints

特色

另外它還提供了应用安全开发注意事项這份文件可以參考,雖然是從 Spec 裡面的 Security Considerations 拉出來的。

豆瓣

文件: http://developers.douban.com/wiki/?title=oauth2

Grant Types

Endpoints

特色

BOX

文件: http://developers.box.com/oauth/

Grant Types

Endpoints

特色

Basecamp (37signals)

文件: https://github.com/37signals/api/blob/master/sections/authentication.md

Grant Types

Endpoints

特色


OAuth 2.0 系列文目錄