Vue3接入钉钉扫码登录

2,066 阅读1分钟

[Talk is cheap. Show me the code]

使用背景:
Vue3后台管理系统结合账号体系接入钉钉扫码登录钉钉开放平台0.05。最新版本钉钉扫码登录请访问钉钉开放平台0.21.0

代码思路:
1:引入ddLogin.js依赖包
2:接口拿到配置的appId实例化钉钉对象并挂载到window上
3:通过监听回调方法拿到 authcode(authcode是前置code,不可直接通信) ,通过authcode 拿到可以跟后端通信的code
4:调用后端接口通过code拿到前端需要的用户信息或者token

1.index.html 引入ddLogin.js依赖包

<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>

2.接口拿到配置的appId实例化钉钉对象并挂载到window上

//ddTalkConfig 是后端提供的拿到配置信息的接口
//这里建立将实例化以及监听毁掉信息的地方抽成一个方法
//便于在后续使用
  initDdInstance() {
    ddTalkConfig().then((res) => {
      const {result: {appKey} } = res;
      state.appKey = appKey;
      state.ddInit(appKey);
      state.ddmessage();
    });
  }
  
   ddInit(appKey) {
    /** 钉钉扫码登录 */
    const url = encodeURIComponent(`https://${window.location.host}/#/login`);
    const goto = encodeURIComponent(`https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appKey}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${url}`);
    window.DDLogin({
      id: 'dd-login',
      goto, // 请参考注释里的方式
      style: 'border:none;background-color:#FFFFFF;',
      width: '365',
      height: '400'
    });
  },
    

3.通过监听回调方法拿到 authcode

    ddmessage() {
        window.addEventListener('message', state.ddcallback, false);
     },
     
    ddcallback(event) {
        const origin = event.origin;
        if (origin === 'https://login.dingtalk.com') {
          // 判断是否来自ddLogin扫码事件。
          const authcode = event.data;
          // 获取到authcode后就可以在这里构造跳转链接进行跳转了
          //url是页面拿到可用code之后的回调地址
          const url = encodeURIComponent(`https://${window.location.host}/#/login`);
          //这一步是拿到真正的可跟钉钉通信的code,这里会进行二次跳转,重载页面后code会在路径中出现。
          window.location.href = `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${state.appKey}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${url}&loginTmpCode=${authcode}`;
          
        }
      },   

4.调用后端接口通过code拿到前端需要的用户信息或者token

  onMounted(() => {
  //这里拿参数自行导入并定义
  // import { useRoute, useRouter } from 'vue-router';
  // const route = useRoute();
  
      const { code } = route.query;
      if (code) {
        ddGetToken({tempAuthCode: code}).then((res) => {
          const {result} = res;
        //这里的result 可以是token 可以是用户信息 请跟后端约定。
        }).catch(() => {
          //catch之后请重载钉钉实例 并去掉过期的code值
          router.push({ query: {}});
          state.initDdInstance();
        });
      } else {
        state.initDdInstance();
      }
    
    });

如果有任何关于本文的意见,欢迎在文章下方留言,我会在看到的第一时间回复。