企业级SSO单点登录与钉钉开放平台对接:周报生成器打通B端
发布时间:2026/9/19 0:49:13 作者:尧图编辑部 阅读量:1,286

企业级SSO单点登录与钉钉开放平台对接周报生成器打通B端在周报生成器的 B 端团队版推进过程中当对接拥有数十名研发人员的中大型技术团队时对方技术负责人通常会提出一个必须满足的准入门槛“我们全公司都在使用钉钉DingTalk进行日常办公与组织架构管理不能让员工再单独注册一套账号密码必须支持钉钉扫码单点登录SSO且员工点击后能自动同步其在钉钉里的部门与直属 Leader 关系。”打通国内主流办公平台钉钉 / 飞书 / 企业微信的OAuth2.0 统一身份认证与组织架构同步是独立软件产品从“小作坊玩具”晋级为“企业级 SaaS 解决方案”的核心分水岭。本文拆解基于钉钉开放平台DingTalk Open Platform实现企业级免密登录与通讯录绑定的端到端实战流程。钉钉单点登录SSO全链路时序浏览器端 (前端登录页) Node.js 服务端 钉钉开放平台 API │ │ │ │── 1. 嵌入钉钉扫码登录组件 ──►│ │ │ (生成包含 AppKey 的二维码) │ │ │ │ │ [ 用户手机钉钉扫码确认 ] │ │ │ │ │ │── 2. 重定向带上 authCode ──►│ │ │ │── 3. 用 authCode 请求 ──►│ │ │ POST /v1.0/oauth2/ │ │ │ userAccessToken │ │ │◄── 返回 userAccessToken ─│ │ │ │ │ │── 4. 获取用户真实身份 ──►│ │ │ GET /v1.0/contact/ │ │ │ users/me │ │ │◄── 返回 unionId, 姓名, │ │ │ 手机号, 部门 ID ─────│ │ │ │ │ │── 5. 自动绑定并关联团队 │ │◄── 6. 下发系统 JWT Token ───│ │核心实现一服务端基于钉钉新版 API 获取用户凭证TypeScript钉钉现已全面升级为新版v1.0RESTful 接口体系// src/services/dingtalkAuthService.ts import axios from axios; import { db } from ../db; import { users, teamMembers } from ../db/schema; import { eq } from drizzle-orm; import { generateJWT } from ../lib/jwt; import { nanoid } from nanoid; const DINGTALK_CLIENT_ID process.env.DINGTALK_APP_KEY!; const DINGTALK_CLIENT_SECRET process.env.DINGTALK_APP_SECRET!; export interface DingtalkUserInfo { unionId: string; openId: string; nick: string; avatarUrl?: string; mobile?: string; } export async function authenticateWithDingtalkCode(authCode: string, teamId?: string): Promise{ token: string; user: any } { // 1. 根据前端传来的 authCode 换取用户个人 userAccessToken const tokenRes await axios.post(https://api.dingtalk.com/v1.0/oauth2/userAccessToken, { clientId: DINGTALK_CLIENT_ID, clientSecret: DINGTALK_CLIENT_SECRET, code: authCode, grantType: authorization_code }); const { accessToken } tokenRes.data; // 2. 根据 userAccessToken 获取当前登录用户的基本信息 const userRes await axios.get(https://api.dingtalk.com/v1.0/contact/users/me, { headers: { x-acs-dingtalk-access-token: accessToken } }); const dingUser: DingtalkUserInfo { unionId: userRes.data.unionId, openId: userRes.data.openId, nick: userRes.data.nick, avatarUrl: userRes.data.avatarUrl, mobile: userRes.data.mobile }; // 3. 查库与自动注册逻辑 let user await db.query.users.findFirst({ where: eq(users.dingtalkUnionId, dingUser.unionId) }); if (!user) { user (await db.insert(users).values({ id: usr_${nanoid(10)}, email: dingUser.mobile ? ${dingUser.mobile}dingtalk.internal : ${dingUser.unionId}dingtalk.internal, name: dingUser.nick, avatarUrl: dingUser.avatarUrl, dingtalkUnionId: dingUser.unionId, role: free_user, createdAt: new Date() }).returning())[0]; } // 4. 若携带了团队邀请 teamId自动加入对应团队 if (teamId) { const existingMember await db.query.teamMembers.findFirst({ where: (m, { and, eq }) and(eq(m.teamId, teamId), eq(m.userId, user!.id)) }); if (!existingMember) { await db.insert(teamMembers).values({ id: tm_${nanoid(10)}, teamId, userId: user.id, role: member, joinedAt: new Date() }); } } // 5. 签发系统 JWT 凭证 const token generateJWT({ userId: user.id, role: user.role }); return { token, user }; }核心实现二前端一键内嵌钉钉免密扫码组件在前端登录页中引入钉钉官方 JS SDK直接以 Iframe 形式内嵌高清二维码// src/components/DingtalkQrLogin.tsx import React, { useEffect } from react; import { useNavigate } from react-router-dom; export const DingtalkQrLogin: React.FC{ teamId?: string } ({ teamId }) { const navigate useNavigate(); useEffect(() { // 动态载入钉钉扫码登录 SDK const script document.createElement(script); script.src https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js; script.async true; document.body.appendChild(script); script.onload () { const redirectUri encodeURIComponent(${window.location.origin}/auth/dingtalk/callback${teamId ? ?teamId${teamId} : }); // 初始化钉钉扫码视窗 (window as any).DTFrameLogin( { id: dingtalk-qr-box, width: 300, height: 300 }, { redirect_uri: redirectUri, client_id: process.env.VITE_DINGTALK_APP_KEY, scope: openid corpid, response_type: code, prompt: consent }, (loginResult: any) { // 扫码成功后的重定向处理 const { redirectUrl } loginResult; window.location.href redirectUrl; }, (errorMsg: string) { console.error(钉钉扫码初始化失败:, errorMsg); } ); }; return () { document.body.removeChild(script); }; }, [teamId]); return ( div classNameflex flex-col items-center justify-center p-4 bg-white rounded-2xl border border-slate-200 shadow-sm div iddingtalk-qr-box classNamew-[300px] h-[300px] / span classNametext-xs text-slate-400 mt-2请使用手机钉钉扫码快速登录/span /div ); };B 端商业化突破打通钉钉 SSO 单点登录后企业客户的入驻摩擦力彻底降为零员工无需记新密码钉钉扫一扫 1 秒加入团队极大增强了产品的“企业级安全可信度”成功敲定了两家拥有 50 人研发团队的中型软件公司的年度企业版采购订单单笔客单价突破2,000 元开辟了全新的 B 端大客户增长曲线。