前言
近日鹃觉,開發(fā) DCOS 項目的過程中荆责,曹老板提出為該平臺提供一個 OAuth2 服務,并以此作為平臺的基礎(chǔ)登錄認證方式。
此先臼隔,平臺使用了組內(nèi)的 LDAP 單點登錄嘹裂,用戶的驗證已有現(xiàn)成的服務器處理。在此基礎(chǔ)上的 OAuth2 服務器功能簡單摔握、明確寄狼,考慮嘗試用 nodejs 搭建一個中間件。
OAuth 2.0
OAuth 2.0 是一個關(guān)于授權(quán)(Authorization)的開放網(wǎng)絡(luò)標準氨淌,在全世界范圍內(nèi)得到了廣泛的應用泊愧,目前的版本是2.0版本。因此盛正,OAuth2.0 并不是一個具體的程序或者應用删咱,而是一個協(xié)議,一套完整豪筝、安全的授權(quán)方式的規(guī)范痰滋。
對 OAuth 2.0的規(guī)范,大可以另寫一文詳解续崖,不在此文闡述范圍敲街。此處推薦:
- 阮一峰《理解OAuth 2.0》 ,較為深入淺出
- 官方解釋:RFC 6749
使用 Nodejs
由于 DCOS 官方本身提供了 auth 的基礎(chǔ)模型严望,前端顯示并不需要過多的修改多艇,選擇繼續(xù)沿用 react + browsify + gulp 的實現(xiàn)。服務器端像吻,采用了 express + mongodb 的輕量級框架搭建此中間層應用墩蔓。
完整結(jié)構(gòu):
- react : 應用層 UI
- express : RESTful API 處理
- mongodb : 數(shù)據(jù)持久化
此外,在 Github 上找到了基于 Nodejs 的 OAuth2.0 成熟工具庫 node-oauth2-server萧豆,在理解 OAuth2.0 的基礎(chǔ)上,閱讀其文檔昏名,便可通過實現(xiàn)其 API 便捷的開發(fā)出滿足需求的服務了涮雷。
具體實現(xiàn)
授權(quán)流程
本服務選用了 OAuth2.0 標準的 Authorization Code 授權(quán)方式,其具體的授權(quán)過程如下:
- 打開客戶端轻局,進行本地登錄檢測洪鸭,若尚無本地登錄,則進行后續(xù)步驟
- 客戶端跳轉(zhuǎn)到 OAuth 服務提供的用戶認證界面仑扑,并在 uri 中帶有授權(quán)方式(此處為 authorize_code览爵,但必須標識),客戶端 id镇饮,回調(diào)地址(方便 OAuth 服務器返回應用的界面)
- 用戶進行用戶名密碼登錄蜓竹,此處為 LDAP 驗證
- 驗證成功,服務器生成授權(quán)碼 authentication_code,并附在先前取得的回調(diào) uri 中俱济,返回 DCOS 應用
- DCOS 接收到帶有授權(quán)碼的請求嘶是,說明已經(jīng)獲得了 OAuth服務器的授權(quán),此時帶著客戶端 id蛛碌、客戶端 secret聂喇、授權(quán)碼,向 OAuth 服務器換取 Access Token蔚携。
- DCOS 客戶端得到成功換去的 Token希太,在本地記錄登陸的用戶以及其現(xiàn)有 Token。利用 Token 請求相應可見的資源酝蜒。
API 實現(xiàn)
node-oauth2-server 對 OAuth2.0 的相關(guān)操作提供了處理流誊辉,并將 API 暴露給用戶進行訂制。通過新建 oauth-server 對象并傳參秕硝,調(diào)用其接口芥映,就能實現(xiàn)完整的 OAuth 驗證。
以下為 Authorization Code Grant 方式的說明:
實現(xiàn) Model functions:
如文檔所述远豺,我們一次實現(xiàn)這些接口奈偏,以 getAuthorizationCode 為例:
意思是說,該接口會調(diào)用 saveAuthorizationCode 方法獲取一個已經(jīng)存在的授權(quán)碼躯护。實現(xiàn)此方法惊来,需要嚴格的按照文檔所要求的輸入?yún)?shù),返回 json 格式書寫棺滞。下面是具體的實現(xiàn)示例:
本中間件選用了 mongoose 來操作 mongodb 進行數(shù)據(jù)存儲裁蚁,此處不過多的贅述。代碼大意為继准,根據(jù)傳入的 code 值查找 authenticationCode schema枉证,最終返回完整的 Code 對象。
根據(jù)以上流程移必,一一實現(xiàn) Model function 即可室谚。
URI 規(guī)范
上文中已經(jīng)提及了 OAuth2.0 協(xié)議的規(guī)范 RFC6749,本項目亦嚴格遵循其要求崔泵。(其實不根據(jù)這個要求書寫的話秒赤, node-oauth2-server 的處理流就會報錯)
此處,簡單歸納并列出:
1.跳轉(zhuǎn)到 OAuth認證界面:
http://localhost:3000/?response_type=code&client_id=dc-njuics-cn&redirect_uri=http://localhost%3A4200
2.返回客戶端界面:
http://localhost:4200/auth?code=123
總結(jié)
本次實踐使用 Nodejs 完整地搭建了一個中間件服務器憎瘸,并嚴格遵守 OAuth2.0 協(xié)議入篮,利用開源庫,開發(fā)出了可用性幌甘、可拓展性良好的應用潮售,并即將投入到生產(chǎn)環(huán)境中痊项,獲益匪淺。
至于過程中的坑饲做,莫過于對開源庫 API 文檔閱讀的不細致线婚,抓不住要點,導致控制流各種報錯盆均。大費周章的閱讀源碼塞弊,其實是接口的數(shù)據(jù)格式有誤,小題大做泪姨,導致開發(fā)效率較低游沿。
此外,拿到項目后應有意識的閱讀業(yè)界規(guī)范肮砾,并以此為基礎(chǔ)進行具體實現(xiàn)诀黍,做出的東西才有使用價值。
項目地址:https://github.com/RobottDog/DCOS-Auth仗处,如果喜歡眯勾,請給我一個 star 吧~
個人博客:https://robottdog.com