nodejs實(shí)現(xiàn)OAuth2.0授權(quán)服務(wù)認(rèn)證
OAuth是一種開發(fā)授權(quán)的網(wǎng)絡(luò)標(biāo)準(zhǔn),全拼為open authorization,即開放式授權(quán),最新的協(xié)議版本是2.0。
舉個(gè)栗子:
有一個(gè)"云沖印"的網(wǎng)站,可以將用戶儲(chǔ)存在Google的照片,沖印出來。用戶為了使用該服務(wù),必須讓"云沖印"讀取自己儲(chǔ)存在Google上的照片。
傳統(tǒng)方法是,用戶將自己的Google用戶名和密碼,告訴"云沖印",后者就可以讀取用戶的照片了。這樣的做法有以下幾個(gè)嚴(yán)重的缺點(diǎn)。
- "云沖印"為了后續(xù)的服務(wù),會(huì)保存用戶的密碼,這樣很不安全。
- Google不得不部署密碼登錄,而我們知道,單純的密碼登錄并不安全。
- "云沖印"擁有了獲取用戶儲(chǔ)存在Google所有資料的權(quán)力,用戶沒法限制"云沖印"獲得授權(quán)的范圍和有效期。
- 用戶只有修改密碼,才能收回賦予"云沖印"的權(quán)力。但是這樣做,會(huì)使得其他所有獲得用戶授權(quán)的第三方應(yīng)用程序全部失效。
- 只要有一個(gè)第三方應(yīng)用程序被破解,就會(huì)導(dǎo)致用戶密碼泄漏,以及所有被密碼保護(hù)的數(shù)據(jù)泄漏。
所以O(shè)Auth就誕生了!
- Third-party application:第三方應(yīng)用程序,本文中又稱"客戶端"(client),即上一節(jié)例子中的"云沖印"。
- HTTP service:HTTP服務(wù)提供商,本文中簡(jiǎn)稱"服務(wù)提供商",即上一節(jié)例子中的Google。
- Resource Owner:資源所有者,本文中又稱"用戶"(user)。
- User Agent:用戶代理,本文中就是指瀏覽器。
- Authorization server:認(rèn)證服務(wù)器,即服務(wù)提供商專門用來處理認(rèn)證的服務(wù)器。
- Resource server:資源服務(wù)器,即服務(wù)提供商存放用戶生成的資源的服務(wù)器。它與認(rèn)證服務(wù)器,可以是同一臺(tái)服務(wù)器,也可以是不同的服務(wù)器。
登錄層提供令牌(token)的生成,其中token包括:有效期、權(quán)限范圍??蛻舳四玫絫oken去訪問受限資源。
- access_token:請(qǐng)求資源時(shí)需要攜帶的token,即訪問token。
- refresh_token:刷新token,如果access_token過期,可以使用該token獲取一份新的access_token和新的refresh_token。一般refresh_token時(shí)效性較長(zhǎng),比如一年,而access_token時(shí)效性較短,比如幾分鐘。
- 權(quán)限范圍:即指定客戶端可以獲取的資源權(quán)限范圍。
OAuth授權(quán)模式
OAuth有四種授權(quán)模式,分別為:
- 授權(quán)碼模式(authorization code)
- 簡(jiǎn)化模式(implicit)
- 密碼模式(resource owner password credentials)
- 客戶端模式(client credentials)
1、授權(quán)碼模式
授權(quán)碼模式是最為嚴(yán)密的授權(quán)模式,整體流程為:瀏覽器攜帶必要信息至授權(quán)頁面,正常登錄成功后,返回一個(gè)code(授權(quán)碼),客戶端拿到code后在后臺(tái)獲取拿code換取token。
2、密碼模式
密碼模式,簡(jiǎn)單地理解即為使用用戶名密碼等參數(shù)獲取access_token,它的步驟如下:
- 用戶向客戶端提供用戶名和密碼。
- 客戶端將用戶名和密碼發(fā)給認(rèn)證服務(wù)器,向后者請(qǐng)求令牌。
- 認(rèn)證服務(wù)器確認(rèn)無誤后,向客戶端提供訪問令牌。
3、refresh_token的應(yīng)用
refresh_token被用來獲取新的access_token和refresh_token,使用方式簡(jiǎn)單如下:
refresh_token無效:
使用nodejs實(shí)現(xiàn)OAuth授權(quán)服務(wù)
技術(shù)棧:
- nodejs + eggjs
- eggjs-oAuth-server插件
具體可以參考:
https://github.com/Azard/egg-oauth2-server
https://cnodejs.org/topic/592b2aedba8670562a40f60b
1、code grant模式測(cè)試及單點(diǎn)登錄實(shí)現(xiàn)
這里我們構(gòu)建兩個(gè)站點(diǎn),一個(gè)是7001端口(授權(quán)服務(wù)),一個(gè)是7002端口(客戶端),授權(quán)模式為code grant。
首先是客戶端登錄頁:
單擊按鈕后直接登錄:
可以發(fā)現(xiàn),瀏覽器重定向到授權(quán)服務(wù)地址,并攜帶了response_type、client_id、redirect_uri三個(gè)參數(shù),登錄成功后,瀏覽器會(huì)重定向到redirect_uri指定的地址,即這里的*http://127.0.0.1:7002/auth/redirect*:
如下為授權(quán)服務(wù)的登錄頁寫法
<form action="/oauth2/authorize?{{query}}" id="form1" name="f" method="post"> <div class="input_outer"> <span class="u_user"></span> <input name="username" class="text" style="color: #FFFFFF !important" type="text" placeholder="請(qǐng)輸入賬戶"> </div> <div 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="請(qǐng)輸入密碼"> </div> <div class="mb2"><a class="act-but submit" href="javascript:;" rel="external nofollow" onclick="document.getElementById('form1').submit()" style="color: #FFFFFF">登錄</a></div> </form>
這里的${query}即為客戶端登錄重定向攜帶的完整query,然后是/oauth2/authorize路由的寫法:
app.all('/oauth2/authorize', app.oAuth2Server.authorize());// 獲取授權(quán)碼
這里調(diào)用app.oAuth2Server.authorize()時(shí),插件會(huì)自動(dòng)執(zhí)行重定向操作,首先是重定向到客戶端指定地址,客戶端拿到code和state后,再去授權(quán)層獲取token:
async redirect(){ // 服務(wù)端重定向過來的 console.log(this.ctx.query) const result = await this.ctx.curl('http://127.0.0.1:7001/users/token', { dataType: 'json', // contentType: 'application/x-www-form-urlencoded', // 默認(rèn)格式 method: 'POST', timeout: 3000, data: { grant_type: 'authorization_code', 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模式測(cè)試
首先使用username、password獲取access_token:
用戶名或密碼錯(cuò)誤時(shí)返回:
使用token獲取授權(quán)資源正常返回:
以上內(nèi)容完整源碼參考:https://github.com/caiya/eggjs-oAuth2-server
總結(jié)
- OAuth實(shí)際使用時(shí)要上https,包括客戶端和授權(quán)服務(wù)端
- 授權(quán)服務(wù)可以使用私鑰簽名,客戶端使用公鑰驗(yàn)證,從而保證數(shù)據(jù)安全性
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Node?ORM項(xiàng)目中使用Sequelize實(shí)例詳解
這篇文章主要為大家介紹了Node?ORM項(xiàng)目中使用Sequelize實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04使用 Node.js 對(duì)文本內(nèi)容分詞和關(guān)鍵詞抽取
這篇文章主要介紹了使用 Node.js 對(duì)文本內(nèi)容分詞和關(guān)鍵詞抽取,需要的朋友可以參考下2017-05-05基于NodeJS的前后端分離的思考與實(shí)踐(三)輕量級(jí)的接口配置建??蚣?/a>
Node在整個(gè)環(huán)境中最重要的工作之一就是代理這些業(yè)務(wù)接口,以方便前端(Node端和瀏覽器端)整合數(shù)據(jù)做頁面渲染。如何做好代理工作,使得前后端開發(fā)分離之后,仍然可以在流程上無縫銜接,是我們需要考慮的問題。本文將就該問題做相關(guān)探討,并提出解決方案。2014-09-09在Mac OS上安裝使用Node.js的項(xiàng)目自動(dòng)化構(gòu)建工具Gulp
Gulp是一個(gè)在使用上比Grunt更加簡(jiǎn)潔的自動(dòng)化工具(文中附有對(duì)比),和Node的npm包管理器配合使用非常方便,下面就記錄一下在Mac OS上安裝使用Node.js的項(xiàng)目自動(dòng)化構(gòu)建工具Gulp的方法:2016-06-06express框架中使用jwt實(shí)現(xiàn)驗(yàn)證的方法
這篇文章主要給大家介紹了關(guān)于express框架中使用jwt實(shí)現(xiàn)驗(yàn)證的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用express具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Node.js如何響應(yīng)Ajax的POST請(qǐng)求并且保存為JSON文件詳解
這篇文章主要介紹了關(guān)于Node.js是如何響應(yīng)Ajax的POST請(qǐng)求并且保存為JSON文件的相關(guān)資料,文中介紹的很詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。2017-03-03NodeJS多種創(chuàng)建WebSocket監(jiān)聽的方式(三種)
這篇文章主要介紹了NodeJS多種創(chuàng)建WebSocket監(jiān)聽的方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06