本文以一種簡(jiǎn)化的格式描述OAuth 2.0 ,以幫助開(kāi)發(fā)人員和服務(wù)提供者實(shí)現(xiàn)該協(xié)議。
The OAuth 2 spec(規(guī)范) 讀起來(lái)讓人有點(diǎn)困惑,我寫(xiě)這篇文章是為了幫助用簡(jiǎn)化的格式來(lái)描述術(shù)語(yǔ)。核心規(guī)范將許多決策留給實(shí)現(xiàn)者,通常是基于實(shí)現(xiàn)的安全權(quán)衡。而不是描述所有需要成功實(shí)現(xiàn)OAuth 2的可能的決策,這篇文章做出了適合大多數(shù)實(shí)現(xiàn)的決策。
注意:這篇文章是根據(jù)OAuth 2.0的當(dāng)前最佳實(shí)踐,從2012年的版本得到了更新的。原版本可以在這里找到。here.
Table of Contents (目錄)
- Roles: Applications, APIs and Users
- Creating an App
-
Authorization: Obtaining an access token 授權(quán),獲取一個(gè)令牌
- Web Server Apps
- Single-Page Apps 單頁(yè)面應(yīng)用程序
- Mobile Apps
- Others
- Making Authenticated Requests 制作身份驗(yàn)證的請(qǐng)求
- Differences from OAuth 1.0 區(qū)別OAuth1.0
- Authentication and Signatures 身份驗(yàn)證和簽名
- User Experience and Alternative Authorization Flows 用戶體驗(yàn)和可選授權(quán)流
- Performance at Scale 大規(guī)模集群的性能
- Resources
Roles (角色)
The Third-Party Application: "Client" (第三方應(yīng)用程序:“客戶端”)
客戶端是試圖訪問(wèn)用戶賬戶的應(yīng)用程序。它需要得到用戶的許可才能做到這一功能。
The API: "Resource Server" (API:"資源服務(wù)器")
資源服務(wù)器是用于訪問(wèn)用戶信息的API服務(wù)器。
The Authorization Server(授權(quán)服務(wù)器)
這是提供用戶批準(zhǔn)或拒絕請(qǐng)求的接口服務(wù)器。在較小的規(guī)模中,這可能是與API資源服務(wù)器相同的服務(wù)器,但更大規(guī)模的部署通常會(huì)將其作為單獨(dú)的組件構(gòu)建。
The User: "Resource Owner"(用戶:“資源所有者”)
資源所有者是能夠訪問(wèn)他們部分賬戶信息的人。
Creating an App(創(chuàng)建一個(gè)應(yīng)用程序)
在開(kāi)始OAuth流程之前,你必須先注冊(cè)一個(gè)新的應(yīng)用程序。在注冊(cè)一個(gè)新的應(yīng)用程序的時(shí)候,你通常會(huì)注冊(cè)一些基本信息,比如應(yīng)用程序名稱,網(wǎng)站,標(biāo)識(shí)等等。此外,您必須注冊(cè)一個(gè)重定向URL,以便將用戶重定向到web服務(wù)器,基于瀏覽器或移動(dòng)應(yīng)用程序。
Redirect URIs (重定向的URL)
該服務(wù)只會(huì)將用戶重定向到一個(gè)已注冊(cè)的URL,這有助于防止一些攻擊。任何HTTP重定向URL都必須使用TLS(安全傳輸層協(xié)議)安全保護(hù),因此服務(wù)器將只重定向到以"https"開(kāi)頭的URL。這樣可以防止令牌(tokens)在授權(quán)過(guò)程中被攔截,本地應(yīng)用程序可以注冊(cè)一個(gè)針對(duì)它的重定向URL解決方案。它看起來(lái)像:demoapp://redirect.
Client ID and Secret (客戶端ID 和 密鑰)
在注冊(cè)了你的應(yīng)用之后,你將收到一個(gè)客戶ID和一個(gè)客戶的密鑰??蛻鬒D被認(rèn)為是公共信息,用于構(gòu)建登錄URL,或者包含在網(wǎng)頁(yè)上的JavaScript源代碼中??蛻舻拿荑€必須保密,如果一個(gè)被部署的應(yīng)用不能保守密鑰,比如單頁(yè)javascript應(yīng)用或者原生應(yīng)用,然后,這個(gè)密鑰就不會(huì)被使用了,最理想的情況是,服務(wù)不應(yīng)該首先對(duì)這些類型的應(yīng)用發(fā)布密鑰。
Authorization (授權(quán))
OAuth 2的第一步是獲得用戶的授權(quán),對(duì)于基于瀏覽器或移動(dòng)的應(yīng)用程序來(lái)說(shuō),這通常是通過(guò)向用戶顯示服務(wù)器提供的接口來(lái)實(shí)現(xiàn)的。
OAuth 2為不同的用例提供了幾種“授權(quán)類型”。授權(quán)類型定義是:
Authorization Code for apps running on a web server, browser-based and mobile apps
(授權(quán)碼:對(duì)于在web服務(wù)器上運(yùn)行的應(yīng)用程序,基于瀏覽器和移動(dòng)用友程序)Password for logging in with a username and password
(密碼:使用用戶名和密碼登錄的密碼)Client credentials for application access
(應(yīng)用程序訪問(wèn)的客戶憑據(jù))Implicit was previously recommended for clients without a secret, but has been superceded by using the Authorization Code grant with no secret.
(隱式之前推薦給沒(méi)有密鑰的客戶,但是通過(guò)使用授權(quán)代碼授權(quán),沒(méi)有任何密鑰。已經(jīng)被取代)
下面將詳細(xì)描述每個(gè)用例:
Web Server Apps(網(wǎng)絡(luò)服務(wù)器應(yīng)用程序)
在處理OAuth服務(wù)器時(shí),Web服務(wù)器應(yīng)用程序是您遇到的最常見(jiàn)的應(yīng)用程序類型。Web應(yīng)用程序是用服務(wù)端語(yǔ)言寫(xiě)的,并在服務(wù)器上運(yùn)行,而應(yīng)用程序的源代碼在公共場(chǎng)合是不可用的。這意味著應(yīng)用程序可以在與授權(quán)服務(wù)器通信時(shí)使用它的客戶端機(jī)密,這可以幫助避免一些攻擊向量。
Authorization
創(chuàng)建一個(gè)“登錄”鏈接,將用戶發(fā)送到:
https://oauth2server.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos&state=1234zyx
- code - Indicates that your server expects to receive an authorization code (表明您的服務(wù)器期望收到授權(quán)代碼)
- client_id - The client ID you received when you first created the application (第一次創(chuàng)建應(yīng)用程序時(shí)接收到的客戶ID)
- redirect_uri - Indicates the URI to return the user to after authorization is complete (表示在授權(quán)完成之后將URL返回給用戶)
- scope - One or more scope values indicating which parts of the user's account you wish to access (一個(gè)或者多個(gè)范圍值:指示您希望訪問(wèn)的用戶賬戶的哪些部分)
- state - A random string generated by your application, which you'll verify later (由應(yīng)用程序生成的隨機(jī)字符串,稍后將驗(yàn)證。)
用戶看到授權(quán)提示符:

如果用戶單擊“允許”,該服務(wù)將使用一個(gè)auth(授權(quán))碼將用戶重定向到您的站點(diǎn)。
https://oauth2client.com/cb?code=AUTH_CODE_HERE&state=1234zyx
-
code - The server returns the authorization code in the query string
(服務(wù)器返回查詢字符串中的授權(quán)代碼) -
state - The server returns the same state value that you passed
(服務(wù)器返回您通過(guò)的相同的狀態(tài)值)
您應(yīng)該首先比較這個(gè)狀態(tài)值,以確保它與您開(kāi)始時(shí)的值相匹配。通??梢詫顟B(tài)值存儲(chǔ)在cookie或者會(huì)話中。然后在用戶返回時(shí)進(jìn)行比較。這將確保您的重定向端點(diǎn)不能被欺騙來(lái)嘗試交換任意的授權(quán)代碼。
Token Exchange(令牌交換)
您的服務(wù)器交換用于訪問(wèn)令牌的身份驗(yàn)證碼(授權(quán)碼):
POST https://api.oauth2server.com/token
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
grant_type=authorization_code - The grant type for this flow is authorization_code
(該流程的授權(quán)類型是authorization_code )code=AUTH_CODE_HERE - This is the code you received in the query string
(這是在查詢字符串中接收到的代碼)redirect_uri=REDIRECT_URI - Must be identical to the redirect URI provided in the original link
(必須與原始鏈接中提供的重定向URL相同)client_id=CLIENT_ID - The client ID you received when you first created the application
(你收到你第一次創(chuàng)建應(yīng)用程序時(shí)的客戶端ID)client_secret=CLIENT_SECRET - Since this request is made from server-side code, the secret is included
(由于這個(gè)請(qǐng)求時(shí)由服務(wù)端代碼完成的,所以包含了這個(gè)密鑰)
服務(wù)器以訪問(wèn)令牌和過(guò)期時(shí)間來(lái)應(yīng)答。
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"expires_in":3600
}
或者如果出現(xiàn)了錯(cuò)誤:
{
"error":"invalid_request"
}
安全性:注意,服務(wù)必須要求應(yīng)用程序預(yù)先注冊(cè)它們的重定向URL。
Single-Page Apps(單頁(yè)面應(yīng)用程序)
單頁(yè)面應(yīng)用程序(或基于瀏覽器的應(yīng)用程序)在從網(wǎng)頁(yè)加載源代碼后完全在瀏覽器運(yùn)行。因?yàn)檎麄€(gè)源代碼都可以在瀏覽器中使用,他們不能保持客戶密鑰的機(jī)密性。所以這個(gè)密鑰是不被使用的。該流正好與上面的授權(quán)碼流完全相同。但在最后一步,在不使用客戶端密鑰的情況下,將授權(quán)代碼交換訪問(wèn)令牌。
注意:以前,推薦使用基于瀏覽器的應(yīng)用程序使用“隱式”流“它立即返回一個(gè)訪問(wèn)令牌,并且沒(méi)有令牌交換步驟。在最初編寫(xiě)規(guī)范的時(shí)候,行業(yè)最佳實(shí)踐已經(jīng)改變,建議在不使用客戶端密鑰的情況下使用授權(quán)代碼流。這位創(chuàng)建安全流提供了更多的機(jī)會(huì),例如使用狀態(tài)參數(shù)。引用:Redhat, Deutsche Telekom,Smart Health IT.
Authorization (授權(quán))
創(chuàng)建一個(gè)”登錄“鏈接,將用戶發(fā)送到:
https://oauth2server.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos&state=1234zyx
code - Indicates that your server expects to receive an authorization code
(表明您的服務(wù)器期望收到授權(quán)碼)client_id - The client ID you received when you first created the application
(第一次創(chuàng)建應(yīng)用程序時(shí)接收到的客戶端ID)redirect_uri - Indicates the URI to return the user to after authorization is complete
(表示在授權(quán)完成之后將URL返回給用戶.)scope - One or more scope values indicating which parts of the user's account you wish to access
(一個(gè)或多個(gè)范圍值指定該用戶賬戶的哪些部分你想要訪問(wèn)的)state - A random string generated by your application, which you'll verify later
(由應(yīng)用程序生成的隨機(jī)字符串,稍后將驗(yàn)證。)
用戶看到授權(quán)提示符:

如果用戶單擊”允許“,該服務(wù)將使用一個(gè)auth碼將用戶重定向到您的站點(diǎn)。
https://oauth2client.com/cb?code=AUTH_CODE_HERE&state=1234zyx
code - The server returns the authorization code in the query string
(服務(wù)器返回查詢字符串中的授權(quán)代碼)state - The server returns the same state value that you passed
(服務(wù)器返回您通過(guò)的相同的狀態(tài)值)
您應(yīng)該首先比較這個(gè)狀態(tài)值,以確保它與開(kāi)始時(shí)的值相匹配。通常可以將狀態(tài)值存儲(chǔ)在cookie中,然后在用戶返回時(shí)進(jìn)行比較。這將確保您的重定向端點(diǎn)不能被欺騙來(lái)嘗試交換任意的授權(quán)代碼。
Token Exchange(令牌交換)
POST https://api.oauth2server.com/token
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID