vue3笔记(30-1)对接钉钉登录

本系统的初始登录对接了casdoor,内置可配置的第三方登录。后期开发中,经过成本效益分析,去掉casdoor,自己进行功能开发更合适,所以需要前后端自己对接钉钉。
本篇记录前端 vue3 对接钉钉实践。 

业务需求

系统通过OAuth授权机制可实现钉钉单点登录(SSO登录)。

前期调研

  1. casdoor 原生配置的钉钉登录采用跳转第三方网页形式(https://login.dingtalk.com/oauth2/challenge.htm?client_id=***&redirect_uri=https://door.casdoor.com/callback&scope=openid&response_type=code&prompt=consent&state=***=),扫码后出现允许登录提示。
  2. 通过 casdoor 自带的钉钉登录可以获取到用户的邮箱,通过邮箱地址在公司全量钉钉数据中找到对应用户(姓名、手机号、部门),映射到系统中,与系统用户进行关联;若用户不存在,则引导用户联系系统管理员手动添加进系统。
  3. 使用钉钉登录可以跳钉钉的登录页面,也可以自己生成二维码。

实现思路

  1. 引入 ddLogin.js 依赖包
  2. 接口拿到配置的 appId 实例化钉钉对象并挂载到 window 上
  3. 通过监听回调方法先拿到 authcode,通过 authcode 拿到可以跟后端通信的 code
  4. 调用后端接口通过 code 拿到前端需要的用户信息/token

方法一

  1. 在 index.html 页面中引入钉钉扫码登录JSSDK
    1
    <script src="https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js"></script>
  2. 调用钉钉 SDK,这里需要注意获取到DOM id需要在DOM渲染之后,不要使用 v-if,不然会报错找不到id
    1
    <div id="showDD"></div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    const ddConfig = () => {
    window.DTFrameLogin(
    // DOM包裹容器相关参数
    {
    id: 'showDD',
    width: 300,
    height: 300
    },
    // 统一登录参数
    {
    redirect_uri: encodeURIComponent('http://***/callback'),
    client_id: 'dingxxxxxxxxxxxx',
    scope: 'openid',
    response_type: 'code',
    state: 'xxxxxxxxx',
    prompt: 'consent'
    },
    (loginResult) => {
    // 登录成功后的回调函数
    const { redirectUrl, authCode, state } = loginResult
    // 这里可以直接进行重定向
    window.location.href = redirectUrl
    // 也可以在不跳转页面的情况下,使用code进行授权
    console.log(authCode)
    },
    (errorMsg) => {
    // 登录失败后的回调函数
    // 这里一般需要展示登录失败的具体原因
    alert(`Login Error: ${errorMsg}`)
    }
    )
    }
    通过扫码登录后,会自动跳转到 redirect_uri 页面,并携带codeauthcode参数,此时可以拿到 参数进行后续操作。
    callback 页面中处理回调逻辑
    1
    2
    const code = route.query.code
    const authCode = route.query.authCode

方法二

和方法一类似,只是跳转到钉钉官方认证页面,若客户端钉钉已处于登录状态,则可以点击头像直接登录。若未登录,则需用户手动扫码。

1
2
3
onMounted(() => {
window.location.href = 'https://login.dingtalk.com/oauth2/auth?client_id=dingxxxxxxxxxxxx&redirect_uri=http://localhost:4010/callback&response_type=code&scope=openid'
})

方法三

钉钉内部实现免登

1
npm install dingtalk-jsapi
1
2
3
4
5
6
7
8
9
import * as dd from 'dingtalk-jsapi'
dd.ready(function () {
dd.runtime.permission.requestAuthCode({
corpId: 'ding*******', // 企业id
onSuccess: function (info: any) {
console.log(info)
}
})
})

javascript

附录
Vue3接入钉钉扫码登录
实现登录第三方网站
钉钉实现单点登录
Vue项目实现单点登录(SSO)的逻辑和基本流程