Oauth2是什麼&怎麼用

一 Oauth2這個是爲了方便安全的用戶(第三方)登錄用的。

一開始聽見oauth2這個詞肯定是很懵的。這是啥,鑑權用的?認證用的?授權用的?跟shiro(java)是一個東西嗎?

其實oauth就是一個流程。我們根據這個流程的要求寫代碼、

oauth有一個授權服務器。是作爲用戶的認證用的。對於服務端來說只需實現一個oauth的授權服務器。對於用戶來說(調用授權認證的研發)只需根據流程發請求就可以了。

 

二 Oauth 有四種實體。 下面以用QQ登陸微博爲例。

資源所有者(resource owner) 我們(普通用戶)

資源服務器(resource server) QQ的後臺服務器(獲取賬號,暱稱,頭像等)。

應用程序(client) 微博這個平臺

授權服務器(Authorization Server) 認證QQ & 授權用的。

 

三 oauth有四種方式。 目的是不把密碼暴露給第三方。(即不把QQ賬號密碼暴露給微博)

1.授權碼 authorization code 也是安全等級最高的一版。 支持refresh token    一般都用這個,微博QQ登錄就是這種方式。

2.密碼 password credentials 支持refresh token    這種安全等級低。誰知道client會不會偷摸存你密碼不。一般內部使用

3.簡化模式 implicit 不支持refresh token   這種沒有獲取code的步驟。請求就給token、 沒get到這個的優勢

4.客戶端模式 client credentials 不支持refresh token   這種是被信任的內部client使用。一般內部平臺間使用

注: client_id   client_secret 是用來oauth server鑑別client用的。

下面詳細說明一下各個方式。簡化模式就不說了。

四 客戶端模式。(grant_type = client_credentials)

使用場景: 一般是內部系統之間的API調用。兩個平臺之間調用。調用者是以平臺爲單位。而不是以用戶爲單位。

舉個簡單例子:A平臺調用B平臺的刪除API 爲了防止B 平臺的刪除API不被隨便調用(即拿到cookie就在postman等工具一頓調),使用客戶端授權的方式來處理。爲了保護B平臺資源而使用。

代碼邏輯過程如下

1.A系統根據B系統提供好的client_id client_secret 向B平臺獲取access_token的接口發請求。

默認的接口是/oauth/token 這個要看實現oauth的server是咋定義的。
(client_id client_secret這兩個值存在storage裏。可能在數據庫中可能在緩存中,需要放哪就放哪)

如下圖所示,調用B平臺的oauth server 獲取access_token的接口來獲取access_token

 

2.通過access_token獲取資源

如下圖所示,access_token 可以通過下面這種放到 x-www-form-urlencoded 的方式跟參數一起傳過去。認證並獲取資源。  也可以放到header中。完全取決於你的server是怎麼寫的代碼。馬賽克的是接口參數,跟文章沒啥用。

 

以上:對於客戶端模式的總結就是。一共兩次請求,第一次獲取access_token 第二次獲取資源。

 

五 密碼模式。(grant_type = password)

使用場景 內部系統之間調用。但是要提供密碼。(A平臺向B平臺請求用戶在B平臺的數據)   這個不要在公網使用。密碼暴露給第三方了。這個就是以用戶爲單位的了。

與客戶端模式的區別在於客戶端模式將平臺和用戶(client & resource owner )結合成了一個。 而密碼模式是將client 和 resource owner 拆開了。

這個例子是基於springboot的。例子代碼來源:https://blog.csdn.net/LightOfMiracle/article/details/79151074

"我"來模擬用戶輸入 "我"將密碼給postman    用postman模擬client   springboot項目模擬資源服務器&授權服務器。

 

注:下圖中header有一個屬性 Authorization  對應 Basic dGVzdDoxMjM0NTY=    後面這個串是  client_id:client_secret 用base64編碼的結果。  這個是springboot security整合 oauth的默認方式。(是可以改的)

 

1、"我"將密碼給postman。  postman向oauth server發起請求來獲取access_token

2、我用access_token獲取資源。注意這個access_token要寫在header的Authorization中 對應  token_type access_token (這個是springboot整合oauth的默認方式。)

 

實際上是  /oauth/token 就是往springboot中註冊一個對象來定時存一個access_token等信息。  然後我們調用需要鑑權的接口就是根據 access_token解析對應的數據。

以上:對於密碼模式的總結就是。一共兩次請求,第一次獲取access_token第二次獲取資源。密碼模式就是將調用方設定爲普通的資源擁有者  resource owner 

六 授權碼模式。(grant_type = authorization_code)

使用場景:可以在公網中。也是最常見的。也是最重要的。

1.還是以微博爲例。 登錄選擇以QQ登錄、會轉到如下這個頁面。

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101019034&response_type=code&scope=get_info%2Cget_user_info&redirect_uri=https%3A%2F%2Fpassport.weibo.com%2Fothersitebind%2Fbind%3Fsite%3Dqq%26state%3DCODE-gz-1Ixlzc-2fV3fU-I68ubvIkiMfbOlvf25365%26bentry%3Dminiblog%26wl%3D&display=

拆一下。可以看到    client_id=101019034這個客戶端id這個是標識微博這個平臺用的。

response_type = code 這個是必須這麼寫。

scope可選項。 標識範圍

redirect_uri 請求返回要重定向的地址。

state  這個是一個隨便寫的值。標識用戶的本次請求不會被csrf 篡改。如果有這個參數,會返回這個參數

2.認證並同意授權。這個就是在上面這個頁面輸入QQ賬號密碼在QQ的服務器進行校驗。這個是安全的。上面這個鏈接是QQ方提供的。 校驗成功後會生成一個code值。如果請求帶state會原封不動的將這個值返回回去。

步驟1的response  大概這樣  https://xxxxweibo.com?code=asdad123esd&state=asdqw     

3.取獲取access_token  這個是調用大概這樣的獲取token的接口 https://graph.qq.com/oauth2.0/token  參數如下。

 

返回結果如下

{
"access_token": "a3a961a1-a74d-45ca-9683-ca683efeb144",
"token_type": "bearer",
"refresh_token": "903e6410-d381-4868-bde6-4a76f4112156",
"expires_in": 9999,
"scope": "read write"
}

4.通過access_token獲取資源。

以上:對於授權碼模式的總結就是。一共三次請求,第一次獲取code,第二次獲取access_token 第三次獲取資源。

一個關於什麼時候使用什麼授權方式的圖譜

七 Golang & Oauth2

授權服務器可以使用 gopkg.in/oauth2.v3 這個包來搭建。

選圖框中的兩個可以打開兩個終端  分別  go run client.go   go  run  server.go  運行訪問localhost:9094 可以註冊access_token

訪問資源爲 localhost:9094/try

具體可以仿照example 包中的例子來自己重寫、

 

參考:

https://alexbilbie.com/guide-to-oauth-2-grants/

https://blog.csdn.net/LightOfMiracle/article/details/79151074

 

 

發佈了54 篇原創文章 · 獲贊 25 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章