? ? ? 最近公司需要做一個(gè)單點(diǎn)登陸,但是產(chǎn)品那邊不希望用戶跳轉(zhuǎn)或者打開新的頁面,所以方案使用了iframe 和postmessage來實(shí)現(xiàn)。
? ? ?先簡(jiǎn)單說一下實(shí)現(xiàn)單點(diǎn)登陸的方式。
第一: 使用cookie來做。拿到后端返回的cookies憑證,每次請(qǐng)求帶上。比較常用的方式。
缺點(diǎn)有2個(gè):安全性不高,cookies容易被人竊取。另一個(gè)就是不能跨域
第二:使用token,返回一個(gè)新的token來驗(yàn)證。后端返回一個(gè)token驗(yàn)證,請(qǐng)求的時(shí)候帶上。缺點(diǎn)就是萬一加密驗(yàn)證被獲取了,也容易被人攻擊。
第三:就是頁面跳轉(zhuǎn)。后端返回一個(gè)加密的token,跳轉(zhuǎn)到子應(yīng)用。缺點(diǎn)就是需要跳轉(zhuǎn),用戶體驗(yàn)稍微差點(diǎn)。
我們采取一個(gè)比較特殊的方式,在react項(xiàng)目中,iframe上面使用postMessage去完成請(qǐng)求拿到token完成單點(diǎn)登陸。
直接貼代碼了。
發(fā)送請(qǐng)求
const sendMessage = (frameId, originSrc, message) => {
let sendData = {
data: message,
i_token:window.localStorage.getItem('kp.token')
};
let id = frameId ||0;
window.frames[id].postMessage(JSON.stringify(sendData), originSrc);
}
監(jiān)聽并且回復(fù)請(qǐng)求
const listenMessage = (source, message) => {
window.addEventListener('message',function(event){
if (event.origin !== source)
return;
let data = {
msg: message,
i_token:window.localStorage.getItem('kp.token')
}
event.source.postMessage(JSON.stringify(data), event.origin);
},false);
}
postMessage 并且不像http請(qǐng)求一樣可以監(jiān)聽,所以不同類型的文件傳輸方式都沒有經(jīng)過檢驗(yàn),看文檔上面目前只允許字符串類型。