站長資訊網
        最全最豐富的資訊網站

        什么是單點登錄系統?用nodejs怎么實現?

        什么是單點登錄系統?用nodejs怎么實現?下面本篇文章給大家介紹一下使用node實現單點登錄系統的方法,希望對大家有所幫助!

        什么是單點登錄系統?用nodejs怎么實現?

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

        一. 基礎知識

        1.1 同源策略

        源 = 協議 + 域名 +端口

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

        • https://www.a.com ❌(協議不同)
        • http://www.b.com ❌(域名不同)
        • http://www.a.com:3000 ❌(端口不同)

        同源策略是瀏覽器的行為,它通過確保應用下的資源只能被本應用訪問,來保證安全。

        1.2 會話機制

        由于http協議是無狀態協議(客戶端和服務器端數據交換完畢,會關閉連接,下次請求重新建立連接),但我們需要做記住密碼等功能時,很明顯需要將會話記錄下來。【相關教程推薦:nodejs視頻教程】

        常用的會話跟蹤就是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'   }})
        登錄后復制

        什么是單點登錄系統?用nodejs怎么實現?

        2. 跨域SSO

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

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

        2.1 跨域寫cookie
        2.1.1 利用< script />標簽跨域寫cookie(jsonp)

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

          <script>     $.ajax({       url: 'https://www.c.com:3000/sso?key=username&value=123',       method: 'get',     })   </script>
        登錄后復制

        但是我們可以通過< script />標簽發起跨域請求,寫入cookie

        <script src="https://www.c.com:3000/sso?key=username&value=123"></script>
        登錄后復制

        或者使用jquery jsonp的方式發起跨域請求,寫入cookie,這種方式的原理也是通過< script />標簽能夠跨域實現的。

         $.ajax({       url: 'https://www.c.com:3000/sso?key=username&value=123',       method: 'get',       dataType:'jsonp'     })
        登錄后復制

        這樣通過< script />標簽就實現了往www.a.com中寫入了domain為www.c.com的跨域cookie.
        什么是單點登錄系統?用nodejs怎么實現?
        后端

        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就行了.
          什么是單點登錄系統?用nodejs怎么實現?

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

        • 瀏覽器未寫入cookie報錯server 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請求,適用于所有瀏覽器,但是缺點也很明顯,每次只能分享給一個服務器。
        什么是單點登錄系統?用nodejs怎么實現?

        2.2 跨域讀cookie
        2.2.1 利用< script />標簽跨域讀cookie(jsonp)

        之前2.1.1利用< script />標簽在www.a.com中寫入了www.c.com的cookie(username,123),現在想要www.a.com請求的時候攜帶上www.c.com的cookie,也就是說要跨域讀cookie.

        其實也是同樣的方法,在www.a.com上利用< script />跨域訪問訪問www.c.com,會自動的帶上domain為www.c.com的cookie。
        www.a.com/index.js

        <script src="https://www.c.com:3000/readCookie"></script>
        登錄后復制

        www.c.com

        router.get('/readCookie', async (ctx, next) => {   let username = ctx.cookies.get('username')   console.log('cookie', username)})
        登錄后復制

        什么是單點登錄系統?用nodejs怎么實現?
        可以看到讀取到了存儲在www.a.com里面domain為www.c.com的cookie.

        3. nodejs實現單點登錄系統實戰

        什么是單點登錄系統?用nodejs怎么實現?
        效果如圖所示:

        • 第一次訪問www.a.com首頁

        • 跳轉到www.c.com:3000登錄頁面,登錄成功后跳轉www.a.com首頁

        • 再次訪問www.a.com首頁,無需登錄直接跳轉

        • 訪問www.b.com首頁,無需登錄直接跳轉

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

        詳細設計:
        什么是單點登錄系統?用nodejs怎么實現?

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲av无码国产精品色午夜字幕 | 国产亚洲精品无码拍拍拍色欲| 中日韩产精品1卡二卡三卡| 国产精品久久99| 人人妻人人澡人人爽精品日本| 久久精品18| 99精品久久久久久久婷婷| 91视频精品全国免费观看| 久久精品国产亚洲av麻豆色欲| 亚洲精品无码成人片在线观看| 精品国产婷婷久久久| 91午夜精品亚洲一区二区三区| 国产福利微拍精品一区二区| 久久国产精品一国产精品金尊| 亚洲国产精品毛片av不卡在线 | 一本精品中文字幕在线| 国内精品久久久久久中文字幕 | 午夜三级国产精品理论三级 | 人妻精品久久久久中文字幕69 | 国产乱子伦精品无码码专区| 亚洲精品无码久久久久sm| 久久夜色精品国产| 精品国产91久久久久久久a| 国产高清日韩精品欧美激情| 四虎成人www国产精品| 国产精品成人观看视频国产| 国产精品无码成人午夜电影| 精品福利一区二区三区免费视频| 无码国内精品久久人妻蜜桃| 最新国产精品精品视频| 亚洲欧美日韩久久精品| 亚洲欧美一级久久精品| 亚洲中文精品久久久久久不卡| 在线精品亚洲| 亚洲av永久无码精品网站 | 91精品无码久久久久久五月天| 久久线看观看精品香蕉国产| 精品国产欧美另类一区| 亚洲精品人成在线观看| 国产成人精品曰本亚洲79ren | 亚洲精品人成在线观看|