首頁 >web前端 >js教程 >在nodejs中如何實作OAuth2.0授權服務認證

在nodejs中如何實作OAuth2.0授權服務認證

亚连
亚连原創
2018-06-14 18:02:193071瀏覽

本篇文章主要介紹了nodejs實作OAuth2.0授權服務認證,現在分享給大家,也為大家做個參考。

OAuth是一種開發授權的網路標準,全拼為open authorization,即開放式授權,最新的協定版本是2.0。

舉個栗子:

有一個"雲沖印"的網站,可以將使用者儲存在Google的照片,沖印出來。使用者為了使用該服務,必須讓"雲端沖印"讀取自己儲存在Google上的照片。

傳統方法是,使用者將自己的Google使用者名稱和密碼,告訴"雲端沖印",後者就可以讀取使用者的照片了。這樣的做法有以下幾個嚴重的缺點。

  1. "雲端沖印"為了後續的服務,會儲存使用者的密碼,這樣就很不安全。

  2. Google不得不部署密碼登錄,而我們知道,單純的密碼登入並不安全。

  3. "雲端沖印"擁有了取得使用者儲存在Google所有資料的權力,使用者沒法限制"雲端沖印"授權的範圍和有效期限。

  4. 使用者只有修改密碼,才能收回賦予"雲沖印"的權力。但是這樣做,會使得其他所有獲得使用者授權的第三方應用程式全部失效。

  5. 只要有一個第三方應用程式被破解,就會導致使用者密碼洩漏,以及所有被密碼保護的資料外洩。

所以OAuth就誕生了!

  1. Third-party application:第三方應用程序,本文中又稱為"客戶端"(cli​​ent),即上一節範例中的"雲沖印"。

  2. HTTP service:HTTP服務提供者,本文簡稱"服務提供者",即上一節範例中的Google。

  3. Resource Owner:資源擁有者,本文又稱為"使用者"(user)。

  4. User Agent:使用者代理,本文就是指瀏覽器。

  5. Authorization server:認證伺服器,也就是服務提供者專門用來處理認證的伺服器。

  6. Resource server:資源伺服器,也就是服務供應商存放使用者產生的資源的伺服器。它與認證伺服器,可以是同一台伺服器,也可以是不同的伺服器。

登入層提供令牌(token)的生成,其中token包含:有效期、權限範圍。客戶端拿到token去存取受限資源。

  1. access_token:要求資源時需要攜帶的token,即存取token。

  2. refresh_token:刷新token,如果access_token過期,可以使用該token取得一份新的access_token和新的refresh_token。一般refresh_token時效性較長,例如一年,而access_token時效性較短,例如​​幾分鐘。

  3. 權限範圍:即指定用戶端可以取得的資源權限範圍。

OAuth授權模式

OAuth有四個授權模式,分別為:

  1. 授權碼模式(authorization code)

  2. 簡化模式(implicit)

  3. 密碼模式(resource owner password credentials)

  4. 客戶端模式(client credentials)

#1、授權碼模式

授權碼模式是最嚴密的授權模式,整體流程為:瀏覽器攜帶必要資訊至授權頁面,正常登入成功後,返回一個code(授權碼),客戶端拿到code後在後台取得拿code換取token。

2、密碼模式

密碼模式,簡單地理解即為使用用戶名稱密碼等參數取得access_token,它的步驟如下:

  1. 使用者向客戶端提供使用者名稱和密碼。

  2. 客戶端將使用者名稱和密碼傳送給認證伺服器,向後者請求令牌。

  3. 認證伺服器確認無誤後,向客戶端提供存取令牌。

3、refresh_token的應用程式

refresh_token被用來取得新的access_token和refresh_token,使用方式簡單如下:

refresh_token無效:

使用nodejs實作OAuth授權服務

技術堆疊:

  1. nodejs eggjs

  2. #eggjs-oAuth-server外掛程式

# 具體可以參考:
https://github.com/Azard/egg-oauth2-server
https://cnodejs.org/topic/592b2aedba8670562a40f60b

#1、code grant模式測試及單一登入實作

這裡我們建構兩個站點,一個是7001埠(授權服務),一個是7002埠(客戶端),授權模式為code grant。

首先是用戶端登入頁:

點擊按鈕後直接登入:

可以發現,瀏覽器重定向到授權服務位址,並攜帶了response_type、client_id、redirect_uri

三個參數,登入成功後,瀏覽器會重定向到

redirect_uri

指定的位址,即這裡的*http://127.0.0.1:7002/auth/redirect*:

如下為授權服務的登入頁寫法

<form action="/oauth2/authorize?{{query}}" id="form1" name="f" method="post">
  <p class="input_outer">
    <span class="u_user"></span>
    <input name="username" class="text" style="color: #FFFFFF !important" type="text" placeholder="请输入账户">
  </p>
  <p class="input_outer">
    <span class="us_uer"></span>
    <input name="password" class="text" style="color: #FFFFFF !important; position:absolute; z-index:100;"value="" type="password" placeholder="请输入密码">
  </p>
  <p class="mb2"><a class="act-but submit" href="javascript:;" rel="external nofollow" onclick="document.getElementById(&#39;form1&#39;).submit()" style="color: #FFFFFF">登录</a></p>
</form>
這裡的${query}

即為客戶端登入重定向攜帶的完整query,然後是

/oauth2/authorize路由的寫法:

app.all(&#39;/oauth2/authorize&#39;, app.oAuth2Server.authorize());// 获取授权码

這裡呼叫

app.oAuth2Server.authorize()

時,外掛程式會自動執行重定向操作,先是重定向到客戶端指定位址,客戶端拿到code和state後,再去授權層取得token:

async redirect(){
  // 服务端重定向过来的
  console.log(this.ctx.query)
  const result = await this.ctx.curl(&#39;http://127.0.0.1:7001/users/token&#39;, {
   dataType: &#39;json&#39;,
   // contentType: &#39;application/x-www-form-urlencoded&#39;, // 默认格式
   method: &#39;POST&#39;,
   timeout: 3000,
   data: {
    grant_type: &#39;authorization_code&#39;,
    code: this.ctx.query.code,
    state: this.ctx.query.state,
    client_id: client_id,
    client_secret: client_secret,
    redirect_uri: redirect_uri,
   }
  });
  this.ctx.body = result.data;
 }
取得到token後正常回傳:

2、password grant模式測試

首先使用username、password取得access_token:

#使用者名稱或密碼錯誤時傳回:

#使用token取得授權資源正常回傳:

    #總結
  1. OAuth實際使用時要上https,包含客戶端與授權服務端

授權服務可以使用私鑰簽名,客戶端使用公鑰驗證,從而確保資料安全性

#上面是我整理給大家的,希望今後會對大家有幫助。

相關文章:

在nodejs express環境中如何將搭建多人聊天室

在Vue webpack中詳細講解基礎配置

###詳細解讀vue-admin與後端(flask)分離結合######

以上是在nodejs中如何實作OAuth2.0授權服務認證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn