前端单点登录实现

1,617 阅读1分钟

通过token校验登录信息

前端单点存储方式

共享本地存储数据token值,token存储方式用的是localStorage 或 sessionStorage,由于这两种都会受到同源策略限制。

跨域存储

想要实现跨域存储,先找到一种可跨域通信的机制,就是 iframe  postMessage,它可以安全的实现跨域通信,不受同源策略限制(后端要修改配置允许iframe打开其他域的地址)。

cross-storage.js(开源库)

原理是用 postMessage 可跨域特性,来实现跨域存储。因为多个不同域下的页面无法共享本地存储数据,我们需要找个“中转页面”来统一处理其它页面的存储数据

3678441071-694971ac024828f3_fix732 (1).png

前端后端通讯

多平台入口页=》某平台中转页=》平台首页

平台中转页

主要将其他平台的token 转成当前平台的信任token值

/** 单点登录获取票据 */
export async function getTicket(token) {
  return request('/getTicket', {
    method: 'GET',
     headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'x-access-token': token },
  });
}
/**免登录 */
export async function singleLogin(data) {
  return request('/singleLogin', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'x-access-token': token    },
    data
  });
}

export default (props: any) => {
  const _singleLogin = async () => {
    try {
      //根据本地token 获取票据 getTicket 通过localStorage.getItem("token")
      const { code, data } = await getTicket(token);
      //免登录成功后跳转页面
      const link = '/home';
      if (code !== 200 || !data) {
        window.location.href = link;
        return;
      }
      //免登接口 获取登录token值
      const res: any = await singleLogin({
        ticket: data,
        source: '',//平台来源
      });
      if (res?.code === 200) {
        localStorage.setItem('tokneKey', res?.data.tokneKey);
        localStorage.setItem('tokenValue', res?.data.tokenValue);
      } else {
        console.log(res?.msg);
        localStorage.removeItem('tokneKey');
        localStorage.removeItem('tokenValue');
      }
      window.location.href = link;
    } catch (e) {
      window.location.href = link;
    }
  };
  useEffect(() => {
    _singleLogin();
  });

  return (
    <div style={{ width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', display: 'flex' }}>
      <Spin spinning={loading}></Spin>
    </div>
  );
};