钉钉账号免登体系(SSO)接入指南

简介: 如果你正在规划一个社区型产品、论坛、博客、或其他开放性Web站点,需要在登录用户之间形成互动性;或者正在对接政府机构、酒店大堂、药房门店等,需要访客先登记后进入;抑或正在设计企业内部系统,不想对接繁琐的iDaaS,但又需要记录和识别访问者的身份,那么,钉钉账号免登或许是你想要的东西,这篇文章应该正好也可以帮到你;本文尽量从初级开发者的角度来讲讲,钉钉账号免登体系的接入方法。

如果你正在规划一个社区型产品、论坛、博客、或其他开放性Web站点,需要在登录用户之间形成互动性;或者正在对接政府机构、酒店大堂、药房门店等,需要访客先登记后进入;抑或正在设计企业内部系统,不想对接繁琐的iDaaS,但又需要记录和识别访问者的身份,那么,钉钉账号免登或许是你想要的东西,这篇文章应该正好也可以帮到你;本文尽量从初级开发者的角度来讲讲,钉钉账号免登体系的接入方法。

副标题:为你的Web站点接入钉钉账号免登体系(钉内免登也适用)。

预期效果

进入站点/打开页面,直接进入钉钉账号授权登录流程,用户同意后直接获取到登录者身份信息。

适用对象

  • PC站点 :通过桌面端浏览器访问的网站。

  • H5站点 :通过手机端扫码、或点击链接访问的网站。

适用场景

  • 场景一:社区型产品、论坛、博客、或其他开放性Web站点,需要在登录用户之间形成互动性。

    • Before:传统的做法是做一套账号系统,提供注册流程,然后再登录使用。

    • After:接入钉钉账号授权体系,可不用繁琐注册、直接免登(可账密、可扫码)。

  • 场景二:政府机构、酒店大堂、药房门店等,需要访客先登记后进入。

    • Before:纸笔登记,然后酌情录入访客系统。

    • After:钉钉扫码,手机上一键快速登记(接入钉钉账号授权体系即可)。

  • 场景三:企业内部系统,不想对接繁琐的iDaaS,但又需要记录和识别访问者的身份。

    • Before:建设简单的账号管理体系,提供内部账号注册流程,登录可用。

    • After:对接钉钉账号授权体系,一键免登快速进入(可账密、可扫码)。

所需接口

接入流程

本文尝试从初级/小白开发者的角度来写,尽可能细、尽可能直白。

准备工作

  • 成为钉钉开发者,具体可参考成为钉钉开发者(有了开发者权限,就可以到钉钉开发者后台创建应用了)。

  • 准备好本地开发环境,Java、PHP、Node.js、Python、C#均可;只要是标准的Web应用开发环境即可,没什么特殊的(这里都不需要管SDK的事儿,开发过程中遇到了再引入,一点都不晚)。

创建应用

  1. 登录钉钉开发者后台 (请确保前面的准备工作已经完成)。

  2. 顶部导航栏选择应用开发>企业内部开发,页面右上角按钮选择创建应用

  3. 在应用创建的弹层中,填写关键信息,最后确定创建

    • 应用类型:选择H5微应用。

    • 开发方式:选择企业自主开发。

    • 应用名称:酌情自定义即可,假定这里起名为扫码免登

  4. 创建好应用以后,就可以获取到应用的AppKey 和AppSecret 了,可以说,这俩东西组合起来就是钉钉开放接口的访问凭证了。

申请接口

  1. 进入应用的开发配置界面,左侧菜单中找到权限管理

  2. 右侧权限配置界面中,权限范围默认选择全部员工,下方接口列表内切换到个人权限,右侧勾选如下两个权限点:

    1. 通讯录个人信息读权限。

    2. 个人手机号信息。

说明

如果还想通过授权获得更多个人信息,酌情申请其他权限点即可。

配置回调

在钉钉授权登录页面,用户点击同意后,页面会跳转回到用户自己的系统,并且此时会携带一个authCode 即临时授权码,此处需要配置的,就是这个回调的地址

  1. 进入应用的开发配置界面,左侧菜单中找到登录与分享

  2. 在右侧回调域名处填写你未来需要接收临时授权码的Web URL,此处假定为本地服务:http://127.0.0.1:3000/callback-for-dingtalk

说明

这里的回调域名可以添加多个,可以分别用于本地开发、预发环境、线上生成环境,甚至供多个Web站点使用(酌情设定)。

开始开发

开发语言不限,目前钉钉的SDK也支持多种语言覆盖,包括Java、PHP、C#、Python、Node.js、Go,酌情选择自己最熟悉的即可。

不过个人感觉,开放平台的本质都是OpenAPI的访问,就是往一个开放接口传参提交数据并获得结果,没啥特别的,所以用不用SDK问题都不是太大。

  1. 创建项目:以下以Node.js项目为例,用Express框架快速初始化一个Web项目。

// 在命令行通过下面几行代码初始化你的Web项目

// 创建项目
mkdir dingtalk-login && cd dingtalk-login
// 初始化,持续回车键即可
npm init
// 安装express:快捷创建web项目很酸爽
npm install --save express express-generator 

// 通过express命令行在当前目录下初始化项目
./node_modules/express-generator/bin/express-cli.js -ef .

// ps:在启动服务之前,可能有些nodejs依赖包还需要安装一下,不妨再install一次
npm install

// 启动服务,然后就可以去浏览器输入地址访问了:http://127.0.0.1:3000
./bin/www
  1. 在文件routes/index.js中开始写主程序代码(意思就是未来通过 https://127.0.0.1:3000/* 进行访问);核心代码就两部分,一个入口,一个回调:

    1. 入口部分,假定命名为 /entry-for-dingtalk ,即未来通过 http://127.0.0.1:3000/entry-for-dingtalk 访问

// 改写这个首页的内容,加一个测试的链接
router.get('/', function(req, res, next) {
  // 页面默认显示一个钉钉免登的链接,点击以后会跳转到下面的router中
  res.send('<a href="/entry-for-dingtalk" target="_blank">点击这里测试钉钉免登</a>');
});

// 扫码免登Demo入口页,完整的访问路径:http://127.0.0.1:3000/entry-for-dingtalk
router.get('/entry-for-dingtalk', function(req, res, next) {
    let clientId = '<这里替换成你自己应用的App Key>';
    let site = 'http://127.0.0.1:3000';

    // 重定向到授权页
    let redirect_uri = encodeURIComponent(`${site}/demo/scan-login-demo`);
    let base_url = 'https://login.dingtalk.com/oauth2/auth';
    
   // 直接跳转到钉钉授权界面
    res.redirect(base_url + "?redirect_uri=" + redirect_uri + "&client_id=" + clientId
                + "&response_type=code&scope=openid&prompt=consent");
});
说明

App Key 从什么地方获取,在前面5.2章节中已经有介绍,自行查看,点击复制即可。

ii. 回调部分,必须与5.4中配置的回调地址保持一致,/callback-for-dingtalk,即未来通过http://127.0.0.1:3000/callback-for-dingtalk 访问

// 扫码免登Demo回调,完整的访问路径:http://127.0.0.1:3000/callback-for-dingtalk
router.get('/callback-for-dingtalk', function(req, res, next) {

    // Step 1:参考如下文档,获取当前登录用户的授权Token
    // 文档:https://open.dingtalk.com/document/orgapp-server/obtain-user-token
    DingtalkClient.request({
        path:'/v1.0/oauth2/userAccessToken',
        method:'POST',
        body:{
            clientId:'<这里替换成你自己应用的App Key>',
            clientSecret: '<这里替换成你自己应用的App Secret>',
            code:req.query.authCode,
            grantType:'authorization_code'
        }
    }).then(data => {
        // Step 2:参考如下文档,获取当前登录用户的个人信息
        // 文档:https://open.dingtalk.com/document/orgapp-server/dingtalk-retrieve-user-information
        return DingtalkClient.request({
            path:'/v1.0/contact/users/me',
            headers: {
                'x-acs-dingtalk-access-token': data.accessToken
            }
        });
    }).then(data => {
        // Step 3:根据获取到的用户授权信息,做相关业务操作
        res.setHeader("Content-Type", "application/json;charset=utf-8");
        res.end(JSON.stringify({
            message:'下面这些内容就是通过免登获取到的个人详细信息了,如果当前已经有账号登录了,可以直接获取到数据',
            data:data   // 这里就是拿到的结果了!!
        },null,4));
    });
});

你可能注意到了上门示例代码中的DingtalkClient.request ,不知道这是什么,这实际上是钉钉OpenApi的简单访问工具,工具定义如下:

// 钉钉OpenApi的访问工具
// github: https://github.com/zxlie/dingtalk-client
let DingtalkClient = {
    /**
     * 钉钉OpenAPI的统一调用入口
     * @param {object} configs 请求配置
     * @p-config {boolean}  isOldApi 是否老版本接口,默认 false
     * @p-config {string}   method   请求方式,GET或者POST
     * @p-config {string}   path     接口地址,如:/v1.0/sso/getToken
     * @p-config {object}   params   需要在接口地址上进行URL拼接的参数
     * @p-config {object}   body     请求方式为POST时,指定提交的内容
     * @p-config {object}   headers  请求头
     * @p-config {function} callback 请求结果的处理回调:function(error,data)
     * @returns  {promise}  返回一个Promise对象
     **/
    request : function(configs) {
        var url = ((isOldApi, path, params) => {
            let _hostConfig = {
                topHost: 'https://oapi.dingtalk.com', // 老版API
                popHost: 'https://api.dingtalk.com'   // 新版API
            };
            let oUrl = new URL((isOldApi ? _hostConfig.topHost : _hostConfig.popHost) + path);

            if (Object.keys(params || {}).length > 0) {
                Object.keys(params, key => oUrl.searchParams.append(key,params[key]));
            }
            return oUrl.toString();
        })(configs.isOldApi, configs.path, configs.params);
        var obj = {
            method:  (configs.method || 'GET').toUpperCase(),
            url: url,
            json: true
        };
        if(obj.method === 'POST' && configs.body) {
            obj.body = configs.body;
        }
        if(configs.headers) {
            obj.headers = configs.headers;
        }
        return new Promise((resolve,reject) => {
            request(obj, (err, response, body) => {
                resolve(body);
            });
        });
    }
};

routes/demo.js的完整代码就不重复贴了,点击这里直接下载。

  1. 上面示例代码中用到了request 包,所以记得在命令行安装一下依赖:

// 安装依赖包:request
npm install --save request

至此,所有的开发工作都结束了,可以去测试了

开始体验

通过命令行工具,重新进入到项目dingtalk-login的目录下,操作如下命令重新启动服务:

// 启动服务,然后就可以去浏览器输入地址访问了:http://127.0.0.1:3000
./bin/www
说明

如果之前你的服务已经启动,记得退出(Win:Ctrl+C,Mac:control+C)。

浏览器访问http://127.0.0.1:3000试一下,是不是跑起来了,按步操作扫码,也拿到了当前用户在钉钉上的个人信息。

11

如果当前电脑上已经登录过钉钉账号,钉钉也是可以帮你自动识别出来的,一键登录即可:

体验升级

上面的链接http://127.0.0.1:3000在PC端浏览器上访问,是没有问题的,但是如果要在手机端测试这个流程,就不能直接用了(大家应该都懂的,因为127.0.0.1表示的本机)。解决方案有两种:

  1. 手机和PC保持在同一局域网内(原理:局域网内可互联)。

    1. 获取PC端在局域网下被分配的IP,如 192.168.3.4,Web站点在PC上的服务即可通过链接 http://192.168.3.4:3000 进行访问。

    2. 在开发者后台,新增登录与分享的回调地址,设置为:http://192.168.3.4:3000/callback-for-dingtalk

    3. routes/index.js中的/ 路由里,也对应将127.0.0.1替换成新IP。

    4. 重启Web服务,在PC或者手机上直接访问 http://192.168.3.4:3000 即可体验最新效果。

    5. BTW:也可以在PC上将连接生成个二维码,用钉钉扫码直接打开,体验更顺滑。

  2. 通过钉钉提供的内网穿透工具来实现(原理:将本地Web服务映射到公网)。

    1. 打开命令行工具,执行以下命令,下载并启动内网穿透工具(附工具文档)。

# 从Git上下载内网穿透工具
git clone https://github.com/open-dingtalk/pierced.git

# 如果是Windows平台,执行下面的命令
cd cd windows_64 && ding -config=ding.cfg -subdomain=abc 3000

# 如果是Mac平台,执行下面的命令
cd mac_64 && chmod 777 ./ding && ./ding -config=./ding.cfg -subdomain=abc 3000
说明

上面-subdomain=abc 里的abc是需要替换成你自己的域名标识的,你希望它叫啥就叫啥(请酌情起名字)。

ii. 在开发者后台,新增【登录与分享】的回调地址,设置为:http://abc.vaiwan.com/callback-for-dingtalk

iii. routes/index.js中的/ 路由里,也对应将127.0.0.1替换成新的公网域名abc.vaiwan.com

iv. 重启Web服务,在PC或者手机上直接访问 http://abc.vaiwan.com 即可体验最新效果。

v. BTW-1:也可以在PC上将连接生成个二维码,用钉钉扫码直接打开,体验更顺滑。

vi. BTW-2:现在把 http://abc.vaiwan.com 发给你的其他同事或朋友,他们也可以访问了(内网穿透的surprise~)。

下载Sample

  1. 从Github下载示例代码

# 下载代码
git clone https://github.com/zxlie/dingtalk-client.git

# 进入Sample目录
cd dingtalk-client/sample/dingtalk-login

# 安装npm包依赖
npm install
  1. 替换入口文件routes/index.js里的App Key 和App Secret (这里不要忘记了前面接入流程中提到的准备工作)。

步骤一:创建应用,获得AppKey和AppSecret(参考接入流程中的创建应用)。

步骤二:申请接口权限(参考接入流程中的申请接口)。

步骤三:配置回调地址(参考接入流程中的配置回调)。

  1. 启动服务,开始体验。

# 启动服务,然后就可以到浏览器里去访问了,http://127.0.0.1:3000
./bin/www

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
7月前
|
移动开发 测试技术 开发工具
【钉钉免登录】(详解)钉钉接口,H5微应用,钉钉免登录及获取当前用户信息
【钉钉免登录】(详解)钉钉接口,H5微应用,钉钉免登录及获取当前用户信息
347 1
【钉钉免登录】(详解)钉钉接口,H5微应用,钉钉免登录及获取当前用户信息
|
存储 安全 Ubuntu
飞书 + Lua 实现企业级组织架构登录认证
飞书是字节跳动旗下一款企业级协同办公软件,本文将介绍如何基于飞书开放平台的身份验证能力,使用 Lua 实现企业级组织架构的登录认证网关。
614 0
飞书 + Lua 实现企业级组织架构登录认证
|
6月前
|
小程序 前端开发 安全
微信小程序OA会议系统个人中心授权登入
微信小程序OA会议系统个人中心授权登入
43 0
|
6月前
|
API
在钉钉中,如何通过API接口实现OA审批和企业业务系统打通?
在钉钉中,如何通过API接口实现OA审批和企业业务系统打通?
272 1
|
6天前
|
监控 数据安全/隐私保护
基于钉钉的阿里云管理实践(一)之账号绑定
在企业日常运营中,通常都需要对阿里云的资源进行管理,对云资源的运行情况进行监控。而钉钉作为一款企业内部沟通协作工具,其与阿里云的结合使用能够提升企业管理效率,实现资源统一管理。 本教程将指导您如何将钉钉账号与阿里云账号进行绑定,以便于更高效地进行资源管理和接收监控告警。
149 0
|
6天前
|
缓存 BI
咨询下,阿里云云效ram账号绑定钉钉账号后,手机端看项目,是空的,怎么解决?
咨询下,阿里云云效ram账号绑定钉钉账号后,手机端看项目,是空的,怎么解决?
49 2
|
5月前
|
移动开发 数据安全/隐私保护
钉钉可以集成企业内网部署的网盘系统实现账号单点登录吗?
最近接到客户的咨询,他们近期在公司局域网里部署了一套文档管理系统(一般叫私有网盘),领导希望平时通过手机钉钉就能访问到这套系统。客户就有些为难,钉钉是部署在公有云互联网环境的,而这套文档管理系统是部署在企业内网的,看上去应该打通不了,于是前来求助。
140 1
|
6月前
|
移动开发 算法 编译器
OAUTH之 钉钉第三方授权登录
OAUTH之 钉钉第三方授权登录
317 0
|
12月前
《阿里云产品手册2022-2023 版》——应用身份服务 IDaaS
《阿里云产品手册2022-2023 版》——应用身份服务 IDaaS
120 0
|
移动开发 Java 数据安全/隐私保护
钉钉一键登录第三方网站
钉钉一键登录第三方网站,这里主要记录一键登录整个实现步骤。登录页面构造好钉钉一键登录链接后的页面效果。
钉钉一键登录第三方网站