目錄
一. 基礎知識
#1.1 同源策略" >#1.1 同源策略
1.2 會話機制" >1.2 會話機制
二. 單一登入
1. 同父網域SSO" >1. 同父網域SSO
2.跨域SSO" >2.跨域SSO
2.1 跨域寫cookie
2.1.1 利用標籤跨域寫cookie(jsonp)
2.1.3 url参数实现跨域信息传递
2.2 跨域读cookie
2.2.1 利用标签跨域读cookie(jsonp)
3. nodejs实现单点登录系统实战
首頁 web前端 js教程 淺析node怎麼實現單一登入系統

淺析node怎麼實現單一登入系統

Oct 28, 2022 am 09:49 AM
nodejs node

怎麼實現單一登入系統?以下這篇文章跟大家介紹一下使用node實作單一登入系統的方法,希望對大家有幫助!

淺析node怎麼實現單一登入系統

單一登入SSO(Single Sign On),就是把2個以上的業務系統中的登入功能剝離出來,形成一個新的系統,做到一次登入後在任意的業務系統中都無需登入的效果。

一. 基礎知識

#1.1 同源策略

來源= 協議網域名稱連接埠

以http://www.a.com為例:

  • https://www.a.com ❌(協定不同)
  • # http://www.b.com ❌(網域不同)
  • http://www.a.com:3000 ❌(連接埠不同)

相同策略是瀏覽器的行為,它透過確保應用程式下的資源只能被本應用程式訪問,來保證安全。 【相關教學推薦:nodejs影片教學

1.2 會話機制

由於http協定是無狀態協定(客戶端和伺服器端資料交換完畢,會關閉連接,下次請求重新建立連接),但我們需要做記住密碼等功能時,很明顯需要將會話記錄下來。

常用的會話追蹤就是cookie和session,簡單的理解它們就是可以存放key,value的資料結構,差別在於cookie保存在客戶端,session保存在伺服器端。

二. 單一登入

1. 同父網域SSO

同父網域,如www.app1.aaa.com,www.app2.aaa.com這兩個伺服器都是在.aaa.com的父網域。
預設情況下,兩個伺服器下頁面之間的cookie是互相存取不到的。

但是我們可以透過設定cookie的domain屬性為共通的父網域,使得兩個伺服器下頁面之間的cookie可以互相存取。

router.get('/createCookie', async (ctx, next) => {
  ctx.cookies.set('username', '123', {
    maxAge: 60 * 60 * 1000,
    httpOnly: false,
    path: '/',
    domain:'.a.com' //设置domain为共通的父域名
  });
  ctx.body = "create cookie ok"})router.get('/getCookie', async (ctx, next) => {
  let username=ctx.cookies.get('username')
  if (username){
    ctx.body=username  }else{
    ctx.body='no cookie'
  }})
登入後複製

淺析node怎麼實現單一登入系統

2.跨域SSO

當我們的網域為www.a .com,www.b.com時,無論怎樣設定domain都沒用了。

那麼就要想辦法將身分憑證(token)寫入到所有網域的cookie中

2.1 跨域寫cookie
2.1.1 利用標籤跨域寫cookie(jsonp)

在http://www.a.com/index.js中直接向https://www.c.com:3000/sso直接發送網路請求,是無法跨網域寫入cookie的。

  <script>
    $.ajax({
      url: &#39;https://www.c.com:3000/sso?key=username&value=123&#39;,
      method: &#39;get&#39;,
    })
  </script>
登入後複製

但是我們可以透過標籤發起跨域請求,寫入cookie

<script></script>
登入後複製
登入後複製

或使用jquery jsonp的方式發起跨域請求,寫入cookie,這種方式的原理也是透過標籤能夠跨域實現的。

 $.ajax({
      url: 'https://www.c.com:3000/sso?key=username&value=123',
      method: 'get',
      dataType:'jsonp'
    })
登入後複製

這樣透過標籤就實現了往www.a.com中寫入了domain為www.c.com的跨域cookie.
淺析node怎麼實現單一登入系統
#後端

const options = {
  key: fs.readFileSync(path.join(__dirname, './https/privatekey.pem')),
  cert: fs.readFileSync(path.join(__dirname, './https/certificate.pem')),
  secureOptions: 'TLSv1_2_method' //force TLS version 1.2}var server = https.createServer(options,app.callback());  //只能使用https协议写cookierouter.get('/sso', async (ctx, next) => {
  let {
    key, value  } = ctx.request.query
  ctx.cookies.set(key, value, {
    maxAge: 60 * 60 * 1000, //有效时间,单位毫秒
    httpOnly: false, //表示 cookie 是否仅通过 HTTP(S) 发送,, 且不提供给客户端 JavaScript (默认为 true).
    path: '/',
    sameSite: 'none', //限制第三方 Cookie
    secure: true //cookie是否仅通过 HTTPS 发送
  });
  ctx.body = 'create Cookie ok'})
登入後複製

注意:

  • #瀏覽器未寫入cookie報錯his set-cookie was blocked due to http-only
    http-only:表示cookie 是否僅透過HTTP(S) 傳送,, 且不提供給客戶端JavaScript (預設為true).
    所以要將httpOnly設定為false.

  • 瀏覽器未寫入cookie報錯this set-cookie was blocked due to user preference
    這個真的坑,因為我是無痕模式開啟的瀏覽器,但chrome瀏覽器預設無痕模式下停用第三方cookie,修改為允許所有cookie就行了.
    淺析node怎麼實現單一登入系統

  • #瀏覽器未寫入cookie報錯 this set cookie was blocked because it has the SameSite attribute but Secure not set
    需要設定sameSite和secure屬性

  • #瀏覽器未寫入cookie錯誤封包error Error: Cannot send secure cookie over unencrypted connection 這我覺得是koa框架寫cookie的限製吧,它只能支援https寫cookie…,於是我把www.c.com改為了https伺服器.

2.1.2 p3p協定頭實作IE瀏覽器跨域
上面所說的jsonp的方式在chrome瀏覽器中完美運行,但是IE瀏覽器對於cookie更加嚴格,只用上面方式無法寫入cookie,解決方法就是加上p3p的回應頭。

router.get('/sso', async (ctx, next) => {
  let {
    key, value  } = ctx.request.query
  ctx.cookies.set(key, value, {
    maxAge: 60 * 60 * 1000, //有效时间,单位毫秒
    httpOnly: false,
    path: '/',
    sameSite: 'none',
    secure: true
  });
  ctx.set("P3P", "CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'") //p3p响应头
  ctx.body = 'create Cookie ok'})
登入後複製
2.1.3 url参数实现跨域信息传递

访问http://www.c.com:3000/createToken?from=http://www.a.com/createCookie

www.c.com上生成token后将url重写,带上token,重定向到www.a.com

router.get('/createToken', async (ctx, next) => {
  let { from } = ctx.request.query  let token = "123";
  ctx.response.redirect(`${from}?token=${token}`)})
登入後複製

www.a.com上从url上获取token,存入cookie

router.get('/createCookie', async (ctx, next) => {
  let { token } = ctx.request.query
  ctx.cookies.set('token', token, {
    maxAge: 60 * 60 * 1000, //有效时间,单位毫秒
    httpOnly: false,
    path: '/',
  });
  ctx.body = 'set cookie ok'})
登入後複製

这样就实现了跨域信息的传递.与上面的方式不同,这种方法只是单纯的http请求,适用于所有浏览器,但是缺点也很明显,每次只能分享给一个服务器。
淺析node怎麼實現單一登入系統

2.2 跨域读cookie
2.2.1 利用标签跨域读cookie(jsonp)

之前2.1.1利用标签在www.a.com中写入了www.c.com的cookie(username,123),现在想要www.a.com请求的时候携带上www.c.com的cookie,也就是说要跨域读cookie.

其实也是同样的方法,在www.a.com上利用跨域访问访问www.c.com,会自动的带上domain为www.c.com的cookie。
www.a.com/index.js

<script></script>
登入後複製
登入後複製

www.c.com

router.get('/readCookie', async (ctx, next) => {
  let username = ctx.cookies.get('username')
  console.log('cookie', username)})
登入後複製

淺析node怎麼實現單一登入系統
可以看到读取到了存储在www.a.com里面domain为www.c.com的cookie.

3. nodejs实现单点登录系统实战

淺析node怎麼實現單一登入系統
效果如图所示:

  • 第一次访问www.a.com首页

  • 跳转到www.c.com:3000登录页面,登录成功后跳转www.a.com首页

  • 再次访问www.a.com首页,无需登录直接跳转

  • 访问www.b.com首页,无需登录直接跳转

源码: https://github.com/wantao666/sso-nodejs

详细设计:
淺析node怎麼實現單一登入系統

更多node相关知识,请访问:nodejs 教程

以上是淺析node怎麼實現單一登入系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

nodejs是後端框架嗎 nodejs是後端框架嗎 Apr 21, 2024 am 05:09 AM

Node.js 可作為後端框架使用,因為它提供高效能、可擴展性、跨平台支援、豐富的生態系統和易於開發等功能。

nodejs怎麼連接mysql資料庫 nodejs怎麼連接mysql資料庫 Apr 21, 2024 am 06:13 AM

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

nodejs中的全域變數有哪些 nodejs中的全域變數有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 Apr 21, 2024 am 05:18 AM

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

nodejs和java的差別大嗎 nodejs和java的差別大嗎 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Mar 05, 2025 pm 05:57 PM

PiNetwork節點詳解及安裝指南本文將詳細介紹PiNetwork生態系統中的關鍵角色——Pi節點,並提供安裝和配置的完整步驟。 Pi節點在PiNetwork區塊鏈測試網推出後,成為眾多先鋒積極參與測試的重要環節,為即將到來的主網發布做準備。如果您還不了解PiNetwork,請參考Pi幣是什麼?上市價格多少? Pi用途、挖礦及安全性分析。什麼是PiNetwork? PiNetwork項目始於2019年,擁有其專屬加密貨幣Pi幣。該項目旨在創建一個人人可參與

nodejs是後端開發語言嗎 nodejs是後端開發語言嗎 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一種後端開發語言。它用於後端開發,包括處理伺服器端業務邏輯、管理資料庫連接和提供 API。

nodejs專案怎麼部署到伺服器 nodejs專案怎麼部署到伺服器 Apr 21, 2024 am 04:40 AM

Node.js 專案的伺服器部署步驟:準備部署環境:取得伺服器存取權限、安裝 Node.js、設定 Git 儲存庫。建置應用程式:使用 npm run build 產生可部署程式碼和相依性。上傳程式碼到伺服器:透過 Git 或檔案傳輸協定。安裝依賴項:SSH 登入伺服器並使用 npm install 安裝應用程式相依性。啟動應用程式:使用 node index.js 等命令啟動應用程序,或使用 pm2 等進程管理器。設定反向代理(可選):使用 Nginx 或 Apache 等反向代理路由流量到應用程式

See all articles