單點登錄介紹
單點登錄指的就是在多個應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)兵罢。再簡單點說的話就是單點登錄的本質(zhì)就是在多個應(yīng)用系統(tǒng)中共享登錄狀態(tài)届慈。
就拿阿里舉個例子
天貓?zhí)詫殞崿F(xiàn)了單點登錄,那么你只需要登錄其中的任意一個,在訪問另一個網(wǎng)站時就無須再次登錄了徒溪。
1.1localStroage 實現(xiàn)單點登錄
// 驗證postMessage的傳遞
登錄注冊中心A系統(tǒng)(http://192.168.1.22:8080)在登錄的時候?qū)⒅竽玫降暮诵男畔?token,存儲到對應(yīng)兄弟系統(tǒng)的localStorage中金顿,實現(xiàn)登錄信息共享
init () {
// 獲取 token
const token = "a9bab2fe-7630-43a3-8c9f-10cee0b4253c"
const src = "http://192.168.1.22:8081"
// 動態(tài)創(chuàng)建一個不可見的iframe,在iframe中加載一個跨域HTML
const iframe = document.createElement("iframe")
iframe.src = src
// 使用postMessage()方法將token傳遞給iframe
iframe.onload = () => {
iframe.contentWindow.postMessage(token, src)
// iframe.remove()
}
document.body.append(iframe)
}
B系統(tǒng)也就是 src 值所對應(yīng)系統(tǒng)代碼
/ 在這個iframe所加載的HTML中綁定一個事件監(jiān)聽器鲤桥,當(dāng)事件被觸發(fā)時揍拆,把接收到的token數(shù)據(jù)寫入localStorage
window.addEventListener('message', function (event) {
// console.log('接收到even事件:')
// console.log(event)
// 配置兄弟站點列表
const brotherWebsite = [
// 'http://192.168.1.22:8080'
]
// 如果消息源在兄弟站點中
if (brotherWebsite.includes(event.origin)) {
this.localStorage.setItem('www.suczone.com', event.data)
}
}, false)
完工
1.2 父域Cookie
一般來說Session ID是存在Cookie中的,因此,如何讓 Session ID(或 Token)在多個域中共享的問題也就變成了如何讓多個域名之間共享Cookie。
但是我們知道由于瀏覽器的同源策略,不同域之間是不能互相訪問Cookie的茶凳。但同時我們別忘了Cookie有一個特點,那就是父域中的 Cookie 被子域所共享嫂拴,換言之播揪,子域會自動繼承父域中的Cookie。
利用 Cookie 的這個特點筒狠,不難想到猪狈,將 Session ID(或 Token)保存到父域中不就行了。沒錯辩恼,我們只需要將 Cookie 的 domain 屬性設(shè)置為父域的域名(主域名)雇庙,同時將 Cookie 的 path 屬性設(shè)置為根路徑,這樣所有的子域應(yīng)用就都可以訪問到這個 Cookie 了灶伊。
不過這要求應(yīng)用系統(tǒng)的域名需建立在一個共同的主域名之下疆前,如 tieba.baidu.com 和 map.baidu.com,它們都建立在 baidu.com 這個主域名之下聘萨,那么它們就可以通過這種方式來實現(xiàn)單點登錄竹椒。
總結(jié):此種實現(xiàn)方式比較簡單,但不支持跨主域名米辐。