單點(diǎn)登錄(Single Sign On)曼库,簡(jiǎn)稱為 SSO区岗,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之
SSO的定義是在多個(gè)應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)
SSO 一般都需要一個(gè)獨(dú)立的認(rèn)證中心(passport)毁枯,子系統(tǒng)的登錄均得通過passport慈缔,子系統(tǒng)本身將不參與登錄操作
當(dāng)一個(gè)系統(tǒng)成功登錄以后,passport將會(huì)頒發(fā)一個(gè)令牌給各個(gè)子系統(tǒng)种玛,子系統(tǒng)可以拿著令牌會(huì)獲取各自的受保護(hù)資源藐鹤,為了減少頻繁認(rèn)證瓤檐,各個(gè)子系統(tǒng)在被passport授權(quán)以后,會(huì)建立一個(gè)局部會(huì)話娱节,在一定時(shí)間內(nèi)可以無需再次向passport發(fā)起認(rèn)證
可以選擇將?Session ID?(或?Token?)保存到瀏覽器的?LocalStorage?中挠蛉,讓前端在每次向后端發(fā)送請(qǐng)求時(shí),主動(dòng)將LocalStorage的數(shù)據(jù)傳遞給服務(wù)端
這些都是由前端來控制的肄满,后端需要做的僅僅是在用戶登錄成功后谴古,將?Session ID?(或?Token?)放在響應(yīng)體中傳遞給前端
單點(diǎn)登錄完全可以在前端實(shí)現(xiàn)。前端拿到?Session ID?(或?Token?)后稠歉,除了將它寫入自己的?LocalStorage?中之外掰担,還可以通過特殊手段將它寫入多個(gè)其他域下的?LocalStorage?中
關(guān)鍵代碼如下:
在iframe中加載一個(gè)跨域HTMLvariframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe); // 使用postMessage()方法將token傳遞iframesetTimeout(function(){iframe.contentWindow.postMessage(token,"http://app1.com");},4000);
? ? ? setTimeout(function () {
? ? ? ? iframe.remove();
? ? ? }, 6000); // 在這個(gè)iframe所加載的HTML中綁定一個(gè)事件監(jiān)聽器,當(dāng)事件被觸發(fā)時(shí)怒炸,把接收到的token數(shù)據(jù)寫入localStoragewindow.addEventListener('message',function(event){localStorage.setItem('token',event.data)},false);
// 獲取 tokenvartoken=result.data.token;// 動(dòng)態(tài)創(chuàng)建一個(gè)不可見的iframe带饱,
前端通過?iframe+postMessage()?方式,將同一份?Token?寫入到了多個(gè)域下的?LocalStorage?中阅羹,前端每次在向后端發(fā)送請(qǐng)求之前勺疼,都會(huì)主動(dòng)從?LocalStorage?中讀取Token并在請(qǐng)求中攜帶,這樣就實(shí)現(xiàn)了同一份?Token?被多個(gè)域所共享
此種實(shí)現(xiàn)方式完全由前端控制灯蝴,幾乎不需要后端參與恢口,同樣支持跨域(同樣思路也可實(shí)現(xiàn)一個(gè)地方登錄另一個(gè)地方下線的登錄方式)