人妻精品在线观看一区二区三区,蜜臀av精品一区二区三区网站,中文一区二区三区亚洲欧美,熟女人妇精品一区二区,人妻av在线观看视频,欧美日韩国产三级精品网站,黄色免费网站直接进入,超碰公开福利正在播放,国产毛片乡下农村妇女毛片

什么是單點(diǎn)登錄系統(tǒng)?用nodejs怎么實(shí)現(xiàn)?-全球熱訊

來(lái)源:php中文網(wǎng) | 2023-02-24 20:59:50 |

什么是單點(diǎn)登錄系統(tǒng)?用nodejs怎么實(shí)現(xiàn)?下面本篇文章給大家介紹一下使用node實(shí)現(xiàn)單點(diǎn)登錄系統(tǒng)的方法,希望對(duì)大家有所幫助!


(資料圖)

一. 基礎(chǔ)知識(shí)

1.1 同源策略

源 = 協(xié)議 + 域名 +端口

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

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

同源策略是瀏覽器的行為,它通過(guò)確保應(yīng)用下的資源只能被本應(yīng)用訪(fǎng)問(wèn),來(lái)保證安全。

1.2 會(huì)話(huà)機(jī)制

由于http協(xié)議是無(wú)狀態(tài)協(xié)議(客戶(hù)端和服務(wù)器端數(shù)據(jù)交換完畢,會(huì)關(guān)閉連接,下次請(qǐng)求重新建立連接),但我們需要做記住密碼等功能時(shí),很明顯需要將會(huì)話(huà)記錄下來(lái)。【相關(guān)教程推薦:nodejs視頻教程】

常用的會(huì)話(huà)跟蹤就是cookie和session,簡(jiǎn)單的理解它們就是可以存放key,value的數(shù)據(jù)結(jié)構(gòu),區(qū)別在于cookie保存在客戶(hù)端,session保存在服務(wù)器端。

二. 單點(diǎn)登錄

1. 同父域SSO

同父域,如www.app1.aaa.com,www.app2.aaa.com這兩個(gè)服務(wù)器都是在.aaa.com的父域名。 默認(rèn)情況下,兩個(gè)服務(wù)器下頁(yè)面之間的cookie是互相訪(fǎng)問(wèn)不到的。

但是我們可以通過(guò)設(shè)置cookie的domain屬性為共通的父域名,使得兩個(gè)服務(wù)器下頁(yè)面之間的cookie可以相互訪(fǎng)問(wèn)到。

router.get("/createCookie", async (ctx, next) => {  ctx.cookies.set("username", "123", {    maxAge: 60 * 60 * 1000,    httpOnly: false,    path: "/",    domain:".a.com" //設(shè)置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"  }})

2. 跨域SSO

當(dāng)我們的域名為www.a.com,www.b.com時(shí),無(wú)論怎樣設(shè)置domain都沒(méi)用了。

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

2.1 跨域?qū)慶ookie
2.1.1 利用< script />標(biāo)簽跨域?qū)慶ookie(jsonp)

在http://www.a.com/index.js中直接向https://www.c.com:3000/sso直接發(fā)送網(wǎng)絡(luò)請(qǐng)求,是無(wú)法跨域?qū)懭隿ookie的。

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

但是我們可以通過(guò)< script />標(biāo)簽發(fā)起跨域請(qǐng)求,寫(xiě)入cookie

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

或者使用jquery jsonp的方式發(fā)起跨域請(qǐng)求,寫(xiě)入cookie,這種方式的原理也是通過(guò)< script />標(biāo)簽?zāi)軌蚩缬驅(qū)崿F(xiàn)的。

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

這樣通過(guò)< script />標(biāo)簽就實(shí)現(xiàn)了往www.a.com中寫(xiě)入了domain為www.c.com的跨域cookie. 后端

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協(xié)議寫(xiě)cookierouter.get("/sso", async (ctx, next) => {  let {    key, value  } = ctx.request.query  ctx.cookies.set(key, value, {    maxAge: 60 * 60 * 1000, //有效時(shí)間,單位毫秒    httpOnly: false, //表示 cookie 是否僅通過(guò) HTTP(S) 發(fā)送,, 且不提供給客戶(hù)端 JavaScript (默認(rèn)為 true).    path: "/",    sameSite: "none", //限制第三方 Cookie    secure: true //cookie是否僅通過(guò) HTTPS 發(fā)送  });  ctx.body = "create Cookie ok"})

注意:

瀏覽器未寫(xiě)入cookie報(bào)錯(cuò)his set-cookie was blocked due to http-onlyhttp-only:表示 cookie 是否僅通過(guò) HTTP(S) 發(fā)送,, 且不提供給客戶(hù)端 JavaScript (默認(rèn)為 true). 所以要將httpOnly設(shè)置為false.

瀏覽器未寫(xiě)入cookie報(bào)錯(cuò)this set-cookie was blocked due to user preference這個(gè)真的坑,因?yàn)槲沂菬o(wú)痕模式打開(kāi)的瀏覽器,但是chrome瀏覽器默認(rèn)無(wú)痕模式下禁用第三方cookie,修改為允許所有cookie就行了.

瀏覽器未寫(xiě)入cookie報(bào)錯(cuò)this set cookie was blocked because it has the SameSite attribute but Secure not set需要設(shè)置sameSite和secure屬性

瀏覽器未寫(xiě)入cookie報(bào)錯(cuò)server error Error: Cannot send secure cookie over unencrypted connection這個(gè)我覺(jué)得是koa框架寫(xiě)cookie的限制吧,它只能支持https寫(xiě)cookie…,于是我把www.c.com改為了https服務(wù)器.

2.1.2 p3p協(xié)議頭實(shí)現(xiàn)IE瀏覽器跨域

上面說(shuō)的jsonp的方式在chrome瀏覽器中完美運(yùn)行,但是IE瀏覽器對(duì)于cookie更加嚴(yán)格,只用上面方式無(wú)法寫(xiě)入cookie,解決辦法就是加上p3p的響應(yīng)頭。

router.get("/sso", async (ctx, next) => {  let {    key, value  } = ctx.request.query  ctx.cookies.set(key, value, {    maxAge: 60 * 60 * 1000, //有效時(shí)間,單位毫秒    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響應(yīng)頭  ctx.body = "create Cookie ok"})
2.1.3 url參數(shù)實(shí)現(xiàn)跨域信息傳遞

訪(fǎng)問(wèn)http://www.c.com:3000/createToken?from=http://www.a.com/createCookie

www.c.com上生成token后將url重寫(xiě),帶上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, //有效時(shí)間,單位毫秒    httpOnly: false,    path: "/",  });  ctx.body = "set cookie ok"})

這樣就實(shí)現(xiàn)了跨域信息的傳遞.與上面的方式不同,這種方法只是單純的http請(qǐng)求,適用于所有瀏覽器,但是缺點(diǎn)也很明顯,每次只能分享給一個(gè)服務(wù)器。

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

之前2.1.1利用< script />標(biāo)簽在www.a.com中寫(xiě)入了www.c.com的cookie(username,123),現(xiàn)在想要www.a.com請(qǐng)求的時(shí)候攜帶上www.c.com的cookie,也就是說(shuō)要跨域讀cookie.

其實(shí)也是同樣的方法,在www.a.com上利用< script />跨域訪(fǎng)問(wèn)訪(fǎng)問(wèn)www.c.com,會(huì)自動(dòng)的帶上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)})

可以看到讀取到了存儲(chǔ)在www.a.com里面domain為www.c.com的cookie.

3. nodejs實(shí)現(xiàn)單點(diǎn)登錄系統(tǒng)實(shí)戰(zhàn)

效果如圖所示:

第一次訪(fǎng)問(wèn)www.a.com首頁(yè)

跳轉(zhuǎn)到www.c.com:3000登錄頁(yè)面,登錄成功后跳轉(zhuǎn)www.a.com首頁(yè)

再次訪(fǎng)問(wèn)www.a.com首頁(yè),無(wú)需登錄直接跳轉(zhuǎn)

訪(fǎng)問(wèn)www.b.com首頁(yè),無(wú)需登錄直接跳轉(zhuǎn)

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

詳細(xì)設(shè)計(jì):

更多node相關(guān)知識(shí),請(qǐng)?jiān)L問(wèn):nodejs 教程!

以上就是什么是單點(diǎn)登錄系統(tǒng)?用nodejs怎么實(shí)現(xiàn)?的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

關(guān)鍵詞: 單點(diǎn)登錄系統(tǒng) nodejs node