钉钉企业内部应用单点登录开发

钉钉企业内部应用单点登录开发

最近公司有钉钉单点登录需求,需用用户在钉钉中点击配置好的应用能自动登录到应用当中,我们的应用是移动端H5页面。

配置钉钉相关环境

钉钉单点登录需要注册号钉钉企业,然后配置企业H5应用,并把地址和出口IP等信息配置到应用中,应用的访问页面需要引入钉钉的dingtalk-jsapi,并通过dingtalk-jsapi+corpId获取免登code,后台使用AppKey,AppSecret获取accessToken,然后用AccessToken加上免登陆code等信息获取用户信息,完成单点登录。

开放平台文档地址:https://ding-doc.dingtalk.com/

简单流程如下:

image

钉钉应用模式

钉钉目前有一下几种应用模式

  1. 企业内部应用
  2. 第三方企业应用
  3. 第三方个人应用

我们目前选择的是企业内部应用,第三方应用需要入驻成为钉钉应用服务商,而且需要配置【RDS钉钉云推送数据源】等,操作是比较麻烦,普通公司其实是用不上的,使用【企业内部应用】即可。

注册钉钉企业

https://oa.dingtalk.com/register_new.htm#/

输入手机号注册公司,按照提示填写完信息,然后需要【设置管理密码】:

image
image

钉钉管理后台

钉钉管理后台是注册好钉钉企业之后管理企业信息,通讯录,管理员等信息的平台

https://oa.dingtalk.com/#/login

应用管理

在【钉钉管理后台】点击创建应用或者其他应用设置相关链接就可以进入【钉钉开发者平台】

image

地址是:https://open-dev.dingtalk.com/#/index

新建应用,管理应用等都在此界面操作:

此界面可以看到corpId等信息,jsapi获取code的时候需要。

image
  1. 新建应用
image
  1. 填写应用基本信息
image
  1. 配置应用信息

这里需要选择【开发应用】,快捷链接不能做单点登录,只是快捷方式

【应用首页链接】和【PC端首页地址】分别对应手机和电脑端访问地址,本地可以用hosts写上域名来做配置。

出口IP地址,可以用IP工具查看自己的IP,如果填写不对也没关系,在调用接口的时候的会报错,错误信息里面有自己的出口IP,填写上自己的出口IP即可。如果是发布到正式服务器上,需要根据服务器的出口IP填写。

image
  1. 创建完成
image
  1. 查看App详情
image

注意下:

AgentId:在创建应用时,系统会自动生成一个AgentId,可用于发送企业会话消息等场景。

AppKey:在创建应用时,系统会自动分配一对AppKey和AppSecret,该AppKey是应用开发过程中的唯一性标识。

AppSecret:AppSecret和上面AppKey一同生成,使用AppKey和AppSecret来换取access_token。

应用开发

客户端前台开发

这里使用前台页面的js来获取code,输入要corpId信息,且必须在钉钉的浏览器环境(手机端或者桌面端都可以)中才能正常获取

客户端需要引入dingtalk-jsapi,使用ES6语法在vuejs项目中代码如下:

import * as dd from 'dingtalk-jsapi'

function dingtalkLogin (corpId) {
  dd.ready(() => {
    // dd.ready参数为回调函数,在环境准备就绪时触发,jsapi的调用需要保证在该回调函数触发后调用,否则无效。
    dd.runtime.permission.requestAuthCode({
      corpId, // 每个公司服务商独立的
      onSuccess (result) {
           // 拿到code之后,可以在服务器端通过code、appKey和appSecret等信息获取用户信息了
        if (result.code) {
            console.log(result)
        }
      },
      onFail (err) {
        // log err
      }
    })
  })
}

服务端后台开发

服务端需要根据jsapi中获取到的code来获取用户信息,类似oauth2授权之后拿到的code。

引入jar文件,目前钉钉官方提供的jar似乎没有提交到maven仓库,需要手动下载并引入到自己的工程。

文档地址:https://ding-doc.dingtalk.com/doc#/faquestions/vzbp02

根据需要下载支持的语言,这里用的是java

下载地址:http://open-dev.dingtalk.com/download/openSDK/java

下载之后是个zip:dingtalk-sdk-java.zip,解压之后有编译后的jar和源文件jar

可以放到自己项目当中引用,如果公司有私服仓库也可以install到maven私服仓库,这里把jar直接放到工程的/extra目录下,并使用scope=system方式引入:

<dependency>
    <groupId>com.dingtalk.open</groupId>
    <artifactId>taobao-sdk-java</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/extra/taobao-sdk-java-auto_1479188381469-20200302.jar</systemPath>
</dependency>

开发调用

测试代码如下,由于用的JUnit测试,需要把页面上通过jsapi获取到的code写入代码进行测试:

public class DingtalkLoginTest {

    private static final Logger logger = LoggerFactory.getLogger(DingtalkLoginTest.class);

    private static final String DING_URL = "https://oapi.dingtalk.com";
    private static final String APP_KEY = ""; // 应用的Key
    private static final String APP_SECRET = ""; // 应用的密码

    @Test
    public void test() {
        // code是前台使用jsapi获取到的,然后传递给后台使用
        String code = "xxxxxxxxxxxxxxxxxx"; 
        String accessToken = getAccessToken();
        if (StringUtils.isNotBlank(accessToken)) {
            String userId = getUserId(accessToken, code);
            OapiUserGetResponse userDetail = StringUtils.isNotBlank(userId) ? getUserDetail(userId, accessToken) : null;
            logger.debug("{}", userDetail);
        }
    }

    public String getAccessToken() {
        String result = null;
        DefaultDingTalkClient client = new DefaultDingTalkClient(DING_URL + "/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(APP_KEY);
        request.setAppsecret(APP_SECRET);
        request.setHttpMethod(HttpMethod.GET.name());
        try {
            OapiGettokenResponse response = client.execute(request);
            result = response.isSuccess() ? response.getAccessToken() : null;
        } catch (ApiException e) {
            logger.error("获取钉钉AccessToken错误", e);
        }
        return result;
    }

    public String getUserId(String accessToken, String code) {
        DingTalkClient client = new DefaultDingTalkClient(DING_URL + "/user/getuserinfo");
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(code);
        request.setHttpMethod("GET");
        String userId = null;
        try {
            OapiUserGetuserinfoResponse response = client.execute(request, accessToken);
            userId = response.isSuccess() ? response.getUserid() : null;
        } catch (ApiException e) {
            logger.error("获取钉钉UserId错误", e);
        }
        return userId;
    }

    public OapiUserGetResponse getUserDetail(String userId, String accessToken) {
        DingTalkClient client = new DefaultDingTalkClient(DING_URL + "/user/get");
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(userId);
        request.setHttpMethod("GET");
        OapiUserGetResponse userDetail = null;
        try {
            userDetail = client.execute(request, accessToken);
        } catch (ApiException e) {
            logger.error("获取钉钉UserDetail错误", e);
        }
        return userDetail;
    }
}

测试钉钉单点登录

可以直接使用钉钉桌面版做测试,不过在配置应用的时候需要填写好【PC端首页地址】。

image

访问之后应用H5路径之后,得到js得到当前用户code,传到后台获取用户信息。

开启钉钉调试功能

注意:如果需要开启调试功能,需要在H5应用中把开发人员配置成【开发负责人】,H5页面按F12就可以出现类似Chrome的开发者工具了。

image

参考文档:https://ding-doc.dingtalk.com/doc#/kn6zg7/qg4y64

常见错误信息

如果报IP错误(错误信息中提供了IP地址,并把此IP地址写入到应用出口IP位置):

{
    "errcode":60020,
    "errmsg":"请参考FAQ:https://open-doc.dingtalk.com/microapp/faquestions/cvbtph。错误原因:访问ip不在白名单之中,request ip=124.15.237.12 appKey\u0028dingebhlv5xxxxx\u0029"
}

另外可能报权限错误,根据实际使用的数据来给新建的应用配置权限即可

{
    "errcode":60011,
    "errmsg":"没有调用该接口的权限"
}

配置接口权限:

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容