钉钉开发文档

移动应用接入钉钉指南

更新时间: 2019-4-17

开发依赖SDK下载

Demo下载

  • Android Demo  Android用户注册是需要提供签名,具体步骤请参考压缩包里面“常见问题.docx”这个文件
  • iOS Demo

准备工作

移动应用钉钉登录是基于OAuth2.0协议标准 构建的钉钉OAuth2.0授权登录系统。
在进行钉钉OAuth2.0授权登录接入之前,请到开发者后台申请应用免登的一些关键字段,并获得相应的AppID和AppSecret,申请钉钉登录且通过审核后,可开始接入流程。
开发者后台操作路径如下:

  1. 打开开发者后台

  2. 选择"应用开发"->"移动接入应用"->"分享" ,点击"新增移动应用"创建应用。

image.png

  1. 填写应用信息,包括应用名称、应用描述、应用图标、应用类型等。

image.png

  1. 创建移动应用之后,可以查看相应的AppID和AppSecret。

1、目前移动应用上钉钉登录只提供原生的登录方式,需要用户安装钉钉客户端才能配合使用。
2、对于Android应用,建议总是显示钉钉登录按钮,当用户手机没有安装钉钉客户端时,请引导用户下载安装钉钉客户端。

授权流程说明

钉钉OAuth2.0授权登录让钉钉用户使用钉钉身份安全登录第三方应用或网站,在钉钉用户授权登录已接入钉钉OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(sns_token),通过sns_token可以进行钉钉开放平台授权关系接口调用,从而可实现获取钉钉用户基本开放信息和帮助用户实现基础开放功能等。

钉钉OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:

  1. 第三方发起钉钉授权登录请求,钉钉用户允许授权第三方应用后,钉钉会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数。
  1. 通过code调用接口getuserinfo_bycode获取授权登录用户信息。

获取登录用户信息时序图:

第一步:请求授权Code

移动应用钉钉授权登录

开发者需要配合使用钉钉开放平台提供的SDK进行授权登录请求接入。正确接入SDK后并拥有相关授权域(scope)(即授权的范围,目前钉钉仅支持授权登录,获取用户的基本信息)权限后,开发者移动应用会在终端本地拉起钉钉应用进行授权登录,钉钉用户确认后钉钉将拉起开发者移动应用,并带上授权临时票据(code)。

iOS平台应用授权登录接入代码示例

  1. Info.plist配置查询钉钉授权登录scheme权限。LSApplicationQueriesSchemes中添加dingtalk, dingtalk-open, dingtalk-sso。dingtalk用于查询是否安装钉钉。dingtalk-open用于查询是否支持开放平台接口调用(不需要查询开放平台接口可不填)。dingtalk-sso用于查询是否支持授权登录。注:iOS系统限制LSApplicationQueriesSchemes最多只能有50个,超出的话会有一部分不生效。

  2. Info.plist的URL Types中增加appId,用于钉钉App返回回调。

  3. app启动时注册appId。示例代码:

// 在app启动时注册appId
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 注册AppId;
    [DTOpenAPI registerApp:#该应用的appId#];
    return YES;
}
  1. 发起授权登录。示例代码:
DTAuthorizeReq *authReq = [DTAuthorizeReq new];
authReq.bundleId = #该应用的bundleId#;
BOOL result = [DTOpenAPI sendReq:authReq];
if (result) {
    NSLog(@"授权登录 发送成功.");
}
else {
    NSLog(@"授权登录 发送失败.");
}
  1. 处理回调。示例代码:
// 在app delegate链接处理回调中调用钉钉回调链接处理方法
- (BOOL)application:(UIApplication *)application
            openURL:(nonnull NSURL *)url
  sourceApplication:(nullable NSString *)sourceApplication
         annotation:(nonnull id)annotation
{
    if ([DTOpenAPI handleOpenURL:url delegate:self]) {
        return YES;
    }

    return NO;
}
// delegate实现回调处理方法 onResp:
- (void)onResp:(DTBaseResp *)resp
{
  //授权登录回调参数为DTAuthorizeResp,accessCode为授权码
    if ([resp isKindOfClass:[DTAuthorizeResp class]]) {
        DTAuthorizeResp *authResp = (DTAuthorizeResp *)resp;
        NSString *accessCode = authResp.accessCode;
        // 将授权码交给服务端做SSO
    }
}

Android平台应用授权登录接入代码示例

{
    // send oauth request
    SendAuth.Req req = new SendAuth.Req();
    req.scope = SendAuth.Req.SNS_LOGIN;
    req.state = "test";
    iddShareApi.sendReq(req);
}

入参说明:

参数 是否必须 说明
appid 应用唯一标识,在钉钉开放平台提交应用审核通过后获得
scope 应用授权作用域,如获取用户个人信息则填写(SendAuth.Req.SNS_LOGIN)
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

返回示例:
在DDShareActivity中回调的onResp(baseResp)的方法中,解析钉钉返回的授权临时票据(code)
示例如下(具体实现细节请参照DDShareDemo中的DDShareActivity)

@Override
    public void onResp(BaseResp baseResp) {
        int errCode = baseResp.mErrCode;
        Log.d("dd" , "errorCode==========>"+errCode);
        String errMsg = baseResp.mErrStr;
        Log.d("dd" , "errMsg==========>"+errMsg);
        switch (errCode) {
            case BaseResp.ErrCode.ERR_OK:
                if(baseResp.getType() == ShareConstant.COMMAND_SENDAUTH_V2 && (baseResp instanceof SendAuth.Resp)){
                    SendAuth.Resp resp = (SendAuth.Resp) baseResp;
                    Toast.makeText(this, "授权成功,授权码为:"+resp.code, Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(this, "分享成功", Toast.LENGTH_SHORT).show();
                }
                break;
        }
        finish();
    }

备注: DDShareActivity的路径,需要配置为第三方 App的PackageName.ddshare. DDShareActivity

可拉起钉钉打开授权登录页:

返回说明:
用户点击授权后,钉钉客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。

返回值 说明
ErrCode ERR_OK = 0(用户同意)
ERR_AUTH_DENIED = -4(用户拒绝授权)
ERR_USER_CANCEL = -2(用户取消)
code 用户换取access_token的code,仅在ErrCode为0时有效
state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由钉钉终端回传,state字符串长度不能超过1K

第二步:服务端通过Code获取授权用户的个人信息

通过免登授权码获取用户信息,参数authcode只能使用一次。

请求方式:POST(HTTPS)
请求地址https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=kKlP1QmmiNR4VF&timestamp=1527130370219&accessKey=yourAppId
请求包结构体

{
    "tmp_auth_code": "23152698ea18304da4d0ce1xxxxx"
}

URL签名参数说明:

参数 说明
accessKey 应用的appId
timestamp 当前时间戳,单位是毫秒
signature 通过appSecret计算出来的签名值,签名算法参考

参数说明

参数 参数类型 必须 说明
tmp_auth_code String 用户授权给钉钉开放应用的免登授权码,第一步中获取的code

SDK请求示例(JAVA)

DefaultDingTalkClient  client = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
req.setTmpAuthCode("4a2c5695b78738d495f47b5fee9160cd");
OapiSnsGetuserinfoBycodeResponse response = client.execute(req,"yourAppId","yourAppSecret");

SDK请求示例(PHP):

include "TopSdk.php";
// DingTalkConstant::$METHOD_GET 要与下面调用接口url要求的保持一致
$c = new DingTalkClient(DingTalkConstant::$CALL_TYPE_OAPI, DingTalkConstant::$METHOD_POST , DingTalkConstant::$FORMAT_JSON);
$req = new OapiSnsGetuserinfoBycodeRequest;
$req->setTmpAuthCode("4a2c5695b78738d495f47b5fee9160cd");
$resp=$c->executeWithAccessKey($req, "https://oapi.dingtalk.com/sns/getuserinfo_bycode","yourAppId","yourAppSecret");
var_dump($resp)

返回结果

{ 
    "errcode": 0,
    "errmsg": "ok",
    "user_info": {
        "nick": "张三",
        "openid": "liSii8KCxxxxx",
        "unionid": "7Huu46kk"
    }
}
参数 说明
nick 用户在钉钉上面的昵称
openid 用户在当前开放应用内的唯一标识
unionid 用户在当前开放应用所属的钉钉开放平台账号内的唯一标识

注意:
AppSecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
建议将Appsecret、放在App云端服务器,由云端中转接口调用请求。

以上内容是否对您有帮助:
在文档使用中是否遇到以下问题(多选):
  • 内容错误
  • 更新不及时
  • 链接错误
  • 缺少代码/图片示例
  • 太简单/步骤待完善
手机号
更多建议
提交成功,感谢您的反馈!