# 钉钉第三方登录(网页免登 / OAuth2 授权)实战指南

钉钉第三方登录(网页免登 / OAuth2 授权)实战指南

说明:下面的步骤以 “企业内部 H5/管理后台接入钉钉扫码登录” 为例,流程和钉钉开放平台文档基本一致,核心就是:用户在钉钉里或扫码 → 拿到临时授权码 → 后端用临时代码换取用户身份 → 建立自己系统的登录态。你可以按需要替换成自己语言,这里给出一份常见的 Java(Spring Boot)示例


记得点赞加收藏哦😁😁😁

1. 整体流程长啥样?

  1. 你的前端发起“去钉钉登录”的请求(两种常见方式):
    • A. 在 PC 浏览器上展示一个 钉钉扫码登录二维码
    • B. 在钉钉内置浏览器里访问你的 H5 页面,这时可以走 免登
  2. 用户扫码 / 点授权后,钉钉会把一个 临时授权码(code) 回给你(有的方式是前端拿到再传给你,有的是钉钉直接回调到你配置的 redirect_uri)。
  3. 你的后端拿着这个 code + 应用的 appKey/appSecret 去钉钉服务器换 用户身份信息(userId / unionId / openId 等)。
  4. 拿到钉钉用户身份后,你的系统做一层 本系统用户绑定
    • 已经绑定过:直接把这个系统用户登录;
    • 没绑定过:走一次绑定页面,让他选或绑定账号。
  5. 系统生成自己的 JWT / Session / Token,后面都走你自己的鉴权。

2. 需要准备的东西

  1. 钉钉开发者账号(https://open-dev.dingtalk.com/ )
  2. 创建应用
    • 如果是企业内部用,选「企业内部应用」;
    • 也可以用「自建应用」。
  3. 在应用里拿到:
    • AppKey
    • AppSecret
  4. 配置 回调域名 / 白名单,比如:
    • 授权回调地址:https://your-domain.com/api/dingtalk/callback
    • 前端域名:https://your-domain.com
  5. 服务器要能访问钉钉的开放平台接口(外网)

3. 钉钉登录的几种常见方式

钉钉的登录有几个名字,别被绕晕了,本质都差不多:

  1. 扫码登录(适合 PC 网页)
    • 页面上嵌入钉钉官方提供的二维码 JS
    • 用户用手机钉钉扫 → 钉钉把 code 回给你
  2. H5 免登 / 微应用免登(适合钉钉内打开的页面)
    • 在钉钉里打开你页面时,前端先调用钉钉 JSAPI dd.runtime.permission.requestAuthCode
    • 得到 code 后丢给你后端
  3. OAuth2 静态回调方式
    • 通过钉钉的授权链接跳转,授权完成后回到你的 redirect_uri,带上 code

后端处理这几个方式其实是一样的:拿 code → 换用户信息

下面给你说一个比较通用、实战里最好落地的两段式方案:前端拿 code → 后端换用户


4. 前端:在钉钉内置浏览器里拿临时授权码

如果你的页面就是在钉钉里打开的(最常见情况),可以这样:

  1. 页面引入钉钉 JS SDK(在钉钉开放平台能看到示例)
  2. 调用:
dd.ready(function() {
  dd.runtime.permission.requestAuthCode({
    corpId: "你的企业corpId",
    onSuccess: function(info) {
      // info.code 就是临时授权码
      const code = info.code;
      // 把 code 发给你后台
      fetch('/api/dingtalk/login', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({ code })
      }).then(r => r.json()).then(res => {
        // 收到你系统自己的token,保存起来
      });
    },
    onFail: function(err) {
      console.error(err);
    }
  })
});

注意点:

  • 这个 corpId 在钉钉后台就能看到;
  • 这个临时码是一次性的,有时效的;
  • 这个方式适合“钉钉里打开的 H5/微应用”。

5. 前端:PC 网页扫码登录

如果你是做 PC 管理后台,要让用户拿手机钉钉扫一扫登录,可以用官方的扫码组件。

HTML 里准备一个容器:

<div id="dingtalk_qr"></div>
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<script>
  var redirectUri = encodeURIComponent('https://your-domain.com/api/dingtalk/callback');
  var appId = '你的AppId'; // 在钉钉后台应用详情里
  var gotoUrl = 'https://oapi.dingtalk.com/connect/qrconnect?appid=' + appId
      + '&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + redirectUri;

  var obj = DDLogin({
      id: "dingtalk_qr",
      goto: gotoUrl,
      style: "border:none;background-color:#FFFFFF;",
      width : "365",
      height: "400"
  });
</script>

扫码后,钉钉会跳转到你配置的 redirect_uri,并带上 code,比如:

GET https://your-domain.com/api/dingtalk/callback?code=xxxx&state=STATE

后台这个接口就能拿到 code 继续干活。


6. 后端:用 code 换取用户信息

下面给一个 Java / Spring Boot 的示例思路,方便你直接嵌到项目里。你实际要看你用的是 企业内部应用登录 还是 扫码登录,调用的 URL 会略有差别,整体都遵循:先换 access_token → 再查用户 这套逻辑。

⚠️ 下面的接口地址可能会有版本升级,实际以钉钉开放平台最新文档为准;示例主要看结构。

6.1 先拿企业 access_token

public String getAccessToken() {
    String appKey = "你的appKey";
    String appSecret = "你的appSecret";
    String url = "https://oapi.dingtalk.com/gettoken?appkey=" + appKey + "&appsecret=" + appSecret;
    // 发起HTTP GET请求,拿到access_token
    // 返回结果示例:{"errcode":0,"access_token":"xxx","expires_in":7200}
}

6.2 用前端传来的 code 换 userid

如果你是走的 免登,一般是这样的接口:

  • POST https://oapi.dingtalk.com/topapi/v2/user/getuserinfo
    参数里带 codeaccess_token

示例(伪代码):

@PostMapping("/api/dingtalk/login")
public ResponseEntity<?> dingtalkLogin(@RequestBody Map<String, String> body) {
    String code = body.get("code");
    String accessToken = getAccessToken();

    // 1. 用 code 换 user info
    String url = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo";
    // 这个接口需要POST和特定body,这里用伪代码表示
    // 请求体里通常要传 { "code": code }
    // 带上 access_token

    // 假设你拿到了 dingUserId
    String dingUserId = "解析返回里的userid";

    // 2. 再查这个用户的详细信息(如名字、手机号等)
    // https://oapi.dingtalk.com/topapi/v2/user/get?access_token=xxx
    // 请求里传 corpId + userid

    // 3. 根据 dingUserId 去你自己库里找有没有对应的系统用户
    //    比如 user表里有个 dingtalk_userid 字段
    //    没有的话要么创建,要么让前端走绑定
    String systemToken = createSystemTokenByDingUserId(dingUserId);

    return ResponseEntity.ok(Map.of(
            "token", systemToken,
            "dingUserId", dingUserId
    ));
}

要点:

  • 第一次拿到的通常只是钉钉侧的标识,不是你系统的;
  • 你要自己维护一张“钉钉ID → 系统用户ID”的映射表;
  • 最后返回给前端的一定是你系统自己的 token,别直接把钉钉的返回给前端。

7. 你的系统需要做的表结构(推荐)

搞个简单表:user_third_bind

字段名类型说明
idbigint主键
user_idbigint你系统里的用户ID
third_typevarchar比如 dingtalk
third_user_idvarchar钉钉返回的userid/unionid
extrajson其他信息(名字、头像)
create_timedatetime
update_timedatetime

登录时的逻辑:

  1. 后端拿到钉钉userid
  2. user_third_bind 找有没有这条
  3. 有 → 查出 user_id → 签发你自己系统的token
  4. 没有 → 返回前端一个“未绑定”的状态码,让前端跳到绑定页面

这样你后面要加 企业微信登录飞书登录 都能共用这一张表,登录逻辑是统一的。


8. 回调地址怎么配?

在钉钉开放平台应用的「登录与分享」或相关配置里,找到 回调域名 / 回调地址,把你的地址写进去,比如:

  • https://your-domain.com/api/dingtalk/callback

注意几点:

  1. 必须是 HTTPS(生产环境);
  2. 必须和你前端里跳转的 redirect_uri 一致;
  3. 有时候钉钉会校验域名白名单,域名要和你在钉钉后台配置的一致。

9. 本地调试怎么搞?

  1. 本地起个后端:http://localhost:8080
  2. 用一个内网穿透 / 本地反向代理工具,把本地映射成一个公网 HTTPS,比如:https://test.your-domain.comhttp://localhost:8080
  3. 钉钉后台里配置这个公网地址当回调
  4. 前端本地页面访问本地接口就行了

这样你就能在本地真实走一遍钉钉扫码登录


10. 常见坑

  1. code 已使用 / code 过期:临时授权码只能用一次,而且有效期短,前端千万别复用。
  2. 回调域名不一致:钉钉回调和你配置的不一样,就拿不到 code。
  3. 企业内部应用 vs 三方应用 API 不同:看文档里的接口路径,选对类型。
  4. 前端跨域:如果前端直接调你后端 /api/dingtalk/login,记得开 CORS。
  5. 用户第一次登录还没绑定:别直接报错,给前端一个“去绑定”的提示。
  6. token 缓存access_token 有效期 2 小时,不要每次都去钉钉拿,缓存一下。

11. 小结一下

  • 钉钉登录的核心就是“拿 code → 换用户 → 建立自己系统的会话”。
  • 前端的工作只是把 code 交给你,后端才是主战场。
  • 只要你把“钉钉用户ID → 系统用户ID”这条线绑住了,后面都简单。

如果你是 Java 项目,可以把上面第 6 节拆成:

  1. DingTalkClient:专门调钉钉开放平台
  2. DingTalkAuthService:封装登录逻辑
  3. AuthController:提供接口给前端
    这样结构就挺清爽了。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值