关于单点登陆的理解

42 阅读2分钟

一、单点登陆原理

1、三方协调:小程序H5前端(我方-开发)、小程序APP(主方-已有)、统一用户认证中心(企业)、药品平台(我方-已有)

2、我方平台测试账号,在统一用户中心注册,H5前端地址在小程序APP中单点登陆,用户在APP中登陆我方测试账号,即可在小程序中单点登陆到H5前端。

3、单点登陆:

用户在APP登陆——>统一用户中心下发userToken——>单点登陆跳转带userToken——>拿到userToken到本地后端用户验证接口——>请求统一用户中心解析userToken——>获取到用户信息——>验证是否为平台用户——>下发平台token——>H5接收后端返回的用户信息——>每次请求都将使用自己的token来做业务处理。

二、小程序H5页面开发

1、单点登陆后url携带参数userToken进入首页

xxx.xxx.xxx:9000/drug/?usert…

此处userToken是由第三方提供的统一用户中心接口提供

2、获取userToken,向本地后端请求统一用户认证接口


// *********************** 统一用户认证开始 *********************** //
      // 获取URL参数中的usertoken值作为userToken
      let userToken = options.usertoken || ''

      console.log("获取到userToken信息:" , userToken)

      // 如果获取到了userToken,则调用统一用户认证方法
      if (userToken) {
        try {

          // 使用 fetch 请求替代原有的 
          const response = await fetch('/xxx/xxx/xxx/xxx/unifiedEntry', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({
              caCode: userToken
            })
          });

          console.log('响应状态:', response.status, response.statusText);
          console.log('响应URL:', response.url);
          console.log('响应头:', Object.fromEntries(response.headers.entries()));

          // 先读取为文本,查看原始内容
          const rawText = await response.text();
          console.log('原始响应文本:', rawText);
          console.log('响应文本长度:', rawText.length);
          console.log('响应前100字符:', rawText.substring(0, 100));

          if (!response.ok) {
            throw new Error(`统一认证错误:HTTP error! status: ${response.status}, 响应: ${rawText}`);
          }

          // 检查是否为空
          if (!rawText || rawText.trim() === '') {
            throw new Error('后端返回空响应体');
          }

          // 尝试解析 JSON
          let res;
          try {
            res = JSON.parse(rawText);
          } catch (parseError) {
            console.error('JSON 解析错误:', parseError.message);
            console.error('原始响应:', rawText);
            throw new Error(`响应不是有效的 JSON: ${rawText.substring(0, 200)}`);
          
          console.log("统一用户认证返回结果:" , res)
          if (res) {
            // 根据返回结果构建userInfo对象
            userInfo = {
              id: res.id,
              token: res.token,
              loginId: res.loginId,
              userName: res.userName,
              userMob: res.userMob,
              orgCode: res.orgCode,
              orgName: res.orgName,
              lastLoginTime: res.lastLoginTime,
              orgType: res.orgType
            }
            
            // 设置token和其他信息
            token = res.token
            code = code || 'default_code'
          }
        } catch (e) {
          console.error('调用统一用户认证方法失败:', e)
          console.log('详细的错误响应:', e.response || e)
        }
      }
// *********************** 统一用户认证结束 *********************** //

3、后端调用统一用户认证中心的api接口解析userToken,获取到当前用户信息,返回平台token

4、前端保存用户信息与token,每次请求都将携带token做业务处理。