系统介绍

有两个系统A、B,希望在A系统中嵌入B系统的页面,我们是具备B系统的账号密码的,期望是能在嵌入的B系统不用重新登录。比起SSO等步骤,本文提供了一种相对简单的实现方式,实现步骤如下

  1. 在A系统中通过B系统的账号密码请求B系统获取B系统的鉴权token
  2. B系统新增一个桥接页面
  3. 在A系统通过iframe的形式嵌入B系统的桥接页面的连接,同时发送一个事件,事件参数为第一步请求到的token
  4. B系统的桥接页面获取到token后放到自己的localstorage中或者cookie中,然后再跳转到B系统的主页面

实现代码

A系统

<template>
    <div style="width: 100%" :style="{ height: `${contentHeight}px` }">
        <iframe ref="iframe" style="width: 100%; height: 100%; border: none" :src="url"></iframe>
    </div>
</template>

<script>
import { defineComponent } from 'vue';
import { mapGetters } from 'vuex';
import axios from '@/service/axios';

/**
 * 审批配置
 */
export default defineComponent({
    name: 'AuditSetting',
    data() {
        return {
            domain: undefined,
            token: undefined,
            url: undefined
        };
    },
    computed: {
        ...mapGetters(['contentHeight'])
    },
    created() {
        this.loadInfo();
    },
    methods: {
        /**
         * 向iframe页面发送设置本地存储的消息
         */
        sendMessage() {
            this.$refs.iframe.contentWindow.postMessage(
                JSON.stringify({
                    action: 'setLocalStorage',
                    values: [{ key: 'ZCL_BOOTSTRAP_STATE', value: this.token }]
                }),
                this.domain
            );
        },
        /**
         * 获取iframe页面的本地存储信息
         */
        async loadInfo() {
            const { info } = await axios.get('/v1/business/zCloudFlow/getToken');
            this.domain = info.domain;
            this.token = info.token;
            this.url = `${this.domain}/bridge.html`;
            this.$refs.iframe.onload = () => {
                this.sendMessage();
            };
        }
    }
});
</script>

B系统桥接页面

<!DOCTYPE html>
<html lang="en">
  <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">
    <title>加载</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but application doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <script>
        window.onmessage = function(event) {
            if (event.source !== window.parent) {
                return;
            }
            var message = JSON.parse(event.data);
            if (message && message.action === 'setLocalStorage') {
                var l = message.values.length;
                for (var i = 0; i < l; i += 1) {
                    window.localStorage.setItem(message.values[i].key, message.values[i].value);
                }
                window.location.replace('/');
            }
        };
    </script>
  </body>
</html>
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐