AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
[TOC] ### 实现原理: ~~~ 前后台实现session共享,实现一次登录现在所有子系统 ~~~ ~~~ 后台:每个系统是在不同服务器上的,因此每个服务器上都会有有一个不同的session信息。实现单点登录只需登录一次将不同服务器中的session同步即可。 前端:每个系统登录之后会将session信息设置到cooke中,实现单点登录只需登录一次将cooke跨域传递给不同域实现共享cooke即可 ~~~ ### 前端实现过程 #### 1. 登录成功后设置session信息到cooke中 ~~~ // 用户登录 async userLogin({ commit }, { loginname, loginpwd }) { const key = await getRsaKey(); // rsa加密 const encrypt = new JSEncrypt(); encrypt.setPublicKey(key); const rsapwd = encrypt.encrypt(loginpwd); const data = await loginRsa({ loginName: loginname, loginPwd: rsapwd }); const { userCode, ownRegion } = data; commit(SET_USER_INFO, data); commit(SET_USER_SESSION, userCode); // todo setSession(userCode); return data; }, ······························································ // 设置session值 export function setSession(session = "ADE8DBC9-BD3F-49CD-BDD4-B712BB1C36B0") { return Cookies.set(SESSION_KEY, session, { expires: 0.5 }); } ~~~ #### 2. 路由拦截判断是否有记录的用户信息(没有信息获取信息),获取后将cooke共享 ~~~ router.beforeEach(async (to, from, next) => { // TODO添加session if (isPermission()) { const hasSession = getSession(); if (hasSession) { if (String(to.path).toLowerCase() === "/login") { next({ path: "/" }); } else { if (hasPermissionInfo() && hasUserInfo()) { // 有权限信息进行正常路由跳转 next(); } else { try { await store.dispatch("getUserInfo"); // 无权限信息先获取权限信息 const permission = await store.dispatch("userGetPermission"); if ( permission && Array.isArray(permission) && permission.length > 0 && hasUserInfo() ) { // 如果权限信息获取成功,动态添加路由并继续原来的路由跳转 const accessRoutes = await store.dispatch( "generateRoutes", permission ); router.addRoutes(accessRoutes); // 同步到optios.routes对象中,方便在业务组件内部获取 router.options.routes.push(...accessRoutes); loginLog(); postCrossInfo(); // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record next({ ...to, replace: true }); } else { // 如果权限信息获取不成功,抛出错误,进行错误捕获处理 const errorMsg = "未获取到用户权限"; iview.Message.error(errorMsg); throw new Error(errorMsg); } } catch (error) { // 用户权限获取失败后 清空session,重新登录 await store.dispatch("resetSession"); setRedirect(to.fullPath); next(`/login`); } } } } else { // 无session信息则跳转到登录页面 if (whiteList.indexOf(String(to.path).toLowerCase()) !== -1) { next(); } else { setRedirect(to.fullPath); next(`/login`); } } } else { // fix: Duplicate named routes definition // 开发环境默认在外部导入全部路由,不异步导入 // router.addRoutes(asyncRoutes); if (to.path === "/login") { next({ path: "/" }); } else { next(); } } }); function postCrossInfo() { const { config } = store.getters; const { CROSSDOMAINS } = config; if (CROSSDOMAINS) { if (Array.isArray(CROSSDOMAINS)) { CROSSDOMAINS.forEach(domain => { shareSession(document.cookie, domain); }); } else if ( Object.prototype.toString.call(CROSSDOMAINS) === "[object String]" ) { shareSession(document.cookie, CROSSDOMAINS); } } } ································································· import Url from "url-parse"; const FRAMMEID = "sessionshare"; const createIframe = url => { const iframe = document.createElement("iframe"); iframe.setAttribute("id", FRAMMEID); iframe.style.display = "none"; iframe.src = url; document.body.appendChild(iframe); return iframe; }; const deleteIframe = iframe => { if (iframe) { iframe.parentNode.removeChild(iframe); } }; const shareSession = (data, url) => { const iframe = createIframe(url); const iframeCont = iframe.contentWindow; const { host } = new Url(url); iframe.onload = () => { window.addEventListener("message", e => { if (e.data === "ok") { deleteIframe(iframe); } }); iframeCont.postMessage(data, `http://${host}`); }; }; export default shareSession; ~~~ #### 3. 不同域获取cooke信息并存入cooke中 ~~~ <!-- 监听设置cookie --> <script> window.addEventListener('message', function(e){ typeof(e.data)=='string' && e.data.split(";").forEach(function (cookie) { document.cookie = cookie; }) }, false); </script> ~~~