单点登录token存本地localstorage
1、认证中心获取token存储在本地 -> 要进入子系统时,使用postmessage向子系统发送token,并存储在子系统的localstorage中
// 创建一个iframe,在iframe中加载一个跨域的网页
const iframe = document.createElement('iframe')
iframe.style.height = '0'
iframe.style.display = 'none'
iframe.src = `${url}/settoken.html`
document.body.append(iframe)
// 使用postMessage()方法将token传递给iframe
iframe.onload = () => {
iframe.contentWindow.postMessage(`info|${token}`, url)
// 监听 子系统 的回调
this.listener = window.onmessage = (event) => {
if (event.data === 'jump') {
// 跳转到子系统
window.open(url)
this.listener = null
}
}
}
2、子系统的public文件夹下创建settoken.html,用来存储token
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title></title>
</head>
<body>
<noscript>
<strong>抱歉,javascript被禁用,请开启后重试。</strong>
</noscript>
<div >1111111</div>
</body>
<script>
// 监听跨域跳转获取新token存入localStorage实现获取访问令牌
let listener = window.onmessage = (event) => {
if (Object.prototype.toString.call(event.data).slice(8, -1) === 'String') {
const [key, value] = event.data.split('|')
if (key === 'info') {
localStorage.setItem('Admin-Token',value)
// 告诉上层 window,已保存token,可以开始跳转了
window.parent.postMessage('jump', '*')
listener = null
}
}
}
</script>
</html>
注意:这里使用window.onmessage,用window.addEventListener会导致重复触发
postmessage适用于:在同一域名下的不同子域之间进行通信