背景,现在有A、B两个系统,其中B是乾坤框架的微前端,里面又有若干可以单独运行的系统C、D、E、F,现在的目标是,如果没有登录过其中任一系统,则需要跳转登录页登录,登录后,所有的A-F都不再需要登录,登录token有效期12h,每次访问都重新刷新12h,上面A-F的域名结尾都是abc.com如a.abc.com、b.abc.com
解决思路:利用浏览器的Cookie实现
登录页面登录后,登录前端在Cookie存放token,先来看下面效果
首先是cookie的key值,也就是_micro.common-info
然后value值是自己前端定义的,比如我这里定义了 环境变量+token
然后是Domain,这是个领域的意思,一般用于区分不同的域名
核心代码是setCookie和getCookie,Cookie.js如下
import Cookies from 'js-cookie';
const TOKENKEY = 'xToken';
const COOKIEKEY = '_micro-common-info';
const ENV = process.env.ENV_CONFIG;
const DOMAIN = 'paymentru.com';
const REG = /paymentru\.com$/;
export function getCookie() {
const cookie = getAllCookie()[ENV];
return cookie && cookie[TOKENKEY];
}
export function setCookie(token) {
const cookie = getAllCookie();
if (!cookie[ENV]) {
cookie[ENV] = {};
}
cookie[ENV][TOKENKEY] = token;
// save the token for 1 year
return new Promise((resolve, reject) => {
try {
Cookies.set(COOKIEKEY, cookie, {
domain: getDomain(),
});
resolve();
} catch (error) {
reject(error);
}
});
}
export function removeCookie() {
setCookie('');
return true;
}
function getDomain() {
return ['localhost', '127.0.0.1', '0.0.0.0'].includes(document.domain)
? document.domain : REG.test(document.domain) ? DOMAIN : document.domain;
}
function getAllCookie() {
const cookStr = Cookies.get(COOKIEKEY, {
domain: getDomain(),
});
if (cookStr && typeof cookStr == 'string') {
try {
const cookie = JSON.parse(cookStr);
if (cookie && typeof cookie == 'object') {
return cookie;
}
} catch (e) {
console.error(e);
}
}
return {};
}
其中这里比较关键 const DOMAIN = 'paymentru.com'; const REG = /paymentru\.com$/; function getDomain() { return ['localhost', '127.0.0.1', '0.0.0.0'].includes(document.domain) ? document.domain : REG.test(document.domain) ? DOMAIN : document.domain; }
解释下来的意思就是 getDomain
函数返回当前文档的域名。如果域名是 'localhost'
、'127.0.0.1'
或 '0.0.0.0'
中的一个,它将返回当前域名。否则,它将检查当前域名是否符合正则表达式 /paymentru\.com$/ [这个正则表达式的意思是匹配以paymentru.com结尾的域名]
,如果符合,则返回常量 DOMAIN
的值 'paymentru.com'
,否则返回当前域名
所以ABCD系统登录时,先去paymentru.com这个Domain下指定环境变量的Cookie获取token,这样这些系统都用统一后缀的cookie实现互相免登