1.0.5 • Published 3 years ago

simcloud-chart-engine v1.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

#Simcloud-Portal 为 flow360 应用提供统一的 sso 登录

流程

子应用通过在 url 里添加 ref 参数跳转到 portal, 例如(http://dev-my.simulation.cloud/login?ref=https://dev-admin.simulation.cloud/)。登录成功之后, portal 会在主域(测试环境:.simulation.cloud)的 cookie 写入必要的登录信息, 例如 accessToken/refreshToken/user 等,再跳回到子应用地址(即 ref 指向的地址)。 此时各应用所在的子域就可以读取到 cookie 中的这些信息并使用
测试环境 portal 地址:http://dev-my.simulation.cloud/login

接入指南

1. 由于本 sso 登录基于 cookie 实现,首先需保证开发服务器与 portal 运行在同一父域名下。具体步骤如下

  1. hosts 文件新增配置 127.0.0.1 local.simulation.cloud
  2. devServer 的 host 配置为local.simulation.cloud

2. 当接口出现 401 时,跳转到登录页。可以在一个统一的地方处理这个逻辑,例如 axios 的拦截器

axios.interceptors.response.use(
  function (response) {
    return response;
  },
  function (error) {
    if (error && error.response && 401 === error.response.status) {
      // 跳转到portal的方法
      toLogin();
    }
    return Promise.reject(error);
  }
);
// 以下是toLogin的一个例子
export function toLogin() {
  let { origin, pathname } = window.location;
  // 如果你的应用已经有了一个登录页,假设它的路由是/app/login,
  // 现在想要替换成portal登录,那首先你需要在登录页调用本toLogin方法
  // 并在这里做一个重定向,防止应用登录页和portal登录页来回跳转,形成死循环
  if (pathname.includes('/app/login')) {
    pathname = '/app/case/all';
  }
  window.location.href = `http://dev-my.simulation.cloud/login?ref=${encodeURIComponent(
    origin + pathname
  )}`;
}

3. portal 登录成功后,会往 cookie 里写入如下信息

  1. accessToken string 类型
  2. refreshToken string 类型
  3. user string 类型,JSON 格式,包含极少的用户信息

4. 写入 cookie 完成即会跳回到应用的页面。如果没有跳转,请检查 url 的 querystring 是否携带了 ref 参数

5. 如果成功跳转到了应用的页面,此时应用就可以拿着 cookie 里的信息去获取具体的用户信息,以下是一个例子

// auth HOC, handle auth logic globally
export default function auth(WrappedComponent) {
  return class extends Component {
    constructor(props) {
      super(props);
      this.state = {
        user: getS3User(),
        token: getToken(),
      };
    }

    componentDidMount() {
      const { user } = this.state;
      if (user.noAuth) {
        this.getUserInfo();
      }
    }

    getUserInfo = async () => {
      try {
        const {
          token: { accessToken },
        } = this.state;
        const cookieUser = getCookieUser();
        // accessToken, cookieUser都是cookie中的信息,
        // 你可以复制utils/util.js里的方法,无需自己实现
        const { data } = await api.credential(
          {},
          {
            headers: {
              AUTHORIZATION: 'Bearer ' + accessToken,
              FLOW360USER: cookieUser.identityId,
              FLOW360ACCESSUSER: cookieUser.guestUserIdentity,
            },
          }
        );
        const s3User = {
          secretAccessKey: data.userSecretAccessKey,
          accessKeyId: data.userAccessKey,
          admin: data.role == 'admin',
          guestUserIdentity: data.identityId,
          ...data,
        };
        saveS3User(s3User);
        this.setState({
          user: s3User,
        });
      } catch (e) {
        console.log(e);
      }
    };

    render() {
      const { user } = this.state;
      if (user.noAuth) {
        return null;
      }
      // inject user props
      return <WrappedComponent user={user} {...this.props} />;
    }
  };
}