OAuth 2.0支持幾種grant type,由於安全性不同,所以適用范圍也不同。背景知識:《理解OAuth 2.0》
| grant type | 是否需要secret | 是否出現授權界面 |
|---|---|---|
| 授權碼模式(Authorization Code) | 是 | 是 |
| 隱藏模式(Implicit) | 否 | 是 |
| 密碼模式(Password) | 否 | 否 |
| 客戶端證書模式(Client credentials) | 是 | 否 |
secret需要保密,而常見的使用場景能否保密呢?如下:
| 使用場景 | 能否保密 |
|---|---|
| web server site | 能 |
| web server api | 能 |
| web app(為避免混亂,下面稱為js app) | 不能 |
| mobile app(Android, iOS等) | 不能 |
可以看到app(js,Android, iOS等)無法保密,所以需要無secret的模式才行,也就是隱藏模式(Implicit)或密碼模式(Password)。從安全性和可維護性角度考慮,Password模式是讓用戶直接輸入密碼,所以只提供給廠商自己app使用。第三方app只有隱藏模式(Implicit)可用,各家服務商的安全警告如下:
- Google : Installed apps are distributed to individual machines, and it is assumed that these apps cannot keep secrets. 原文鏈接
- Facebook : This app secret should never be included in client-side code or in binaries that could be decompiled. 原文鏈接
現在來看看常用的賬號體系服務商支持的grant type。
| 賬號體系 | web支持Authorization Code | web支持Implicit | mobile sdk支持Implicit |
|---|---|---|---|
| 支持 | 支持、js sdk支持 | 支持 | |
| 支持 | js sdk支持 | 支持 | |
| Github | 支持 | 否 | 否,無sdk |
| 支持 | 支持 | 支持 | |
| 微信 | 支持 | 否 | 支持,但文檔錯誤 |
| 微博 | 支持 | 支持,但文檔沒說,混亂 | 支持,但文檔沒說,混亂 |
可以看到Github只支持授權碼模式,只能在web server上用,不支持app,請謹慎使用。不過由於github是生產力工具,使用github登錄的第三方網站也都是生產力工具,比如gitbook.com、travis-ci.org,只在web上用,也是可以理解的。
而微信不支持web Implicit,所以只支持web server,不支持web app,在純API架構下,會帶來混亂。
純API架構是只開發一套api,同時支持各種app(js、Android、iOS),而沒有了web server site。架構如圖(https://www.processon.com/view/link/567220ace4b0f79964befccd):

如果再使用OAuth Client即第三方登錄,那它的純API架構如下(https://www.processon.com/view/link/566fe5d1e4b0554d8cfaa6e2):

可以看到大部分公司做API僅供自家app使用,也就是私有API,用這種架構就可以了。多虧了API的HTTP server是自家的,所以也能把授權碼模式加進去,用來支持github/微信,架構如下(https://www.processon.com/view/link/56723463e4b0f79964c05229):

而如果API本身需要開放,就沒了“自家的API”這個概念了,假設叫做api.example.com,那將變成雙重OAuth架構(https://www.processon.com/view/link/5672343ee4b02f55904265bf):

可以想到會有兩種場景:
- 第三方app沒有自己的HTTP server,比如JS app,無法獲取token。如果它們攜帶自己的app key去github/微信獲取用戶授權,跳轉回JS app的地址獲取code,交給api.example.com攜帶secret去github/微信驗證,如果想通過的話,那此app key和secret要對應,即第三方app把自己的secret都告訴api.example.com才行,這樣勉強可以用,但安全風險較大……如果第三方app攜帶example的app key去github/微信獲取用戶授權,跳轉地址不對,無法獲得code,此路不通。
- 第三方app有自己的HTTP server,則可以自己換取token,然后發給api.example.com即可。
