首先详细阅读钉钉官方文档,你想要的东西它都有对应的步骤说明,很详细。如下:
专有钉钉门户https://openplatform-portal.dg-work.cn/portal/#/helpdoc?apiType=QUICK_START&docKey=3355321前言:若你本次的开发暂不需要上架浙政钉,则登录专有钉以后不用注册应用,这里我们只需要看扫码组件接口如何调用那部分就可以。拿到对应的appKey和appsecret即可以去实现扫码登录接口以及获取其他信息接口。注意:这里可能有多个appKey和多个appsecret,我们调用哪个接口就去使用对应的就可以了。
具体步骤:
1.在IRS上注册应用,应用状态为谋划中/开发中;
2.在IRS上申请浙政钉扫码登陆、浙政钉用户.....等一些实际开发需要用到的组件权限;
3.开发商注册浙政钉账号,并激活, 即可扫码登录开发商 ;(这里就是开发对应有一个浙政钉的账号可以登录进去,方便后续扫码登录测试)
4.开发提供姓名,手机号码,我们把它放到专有钉开发组织下面,注意手机号码必须和浙政钉账号的手机号码一致;
5.在专有钉上面注册应用,申请APPKEY和密钥等。拿到对应的 appkey 以及密钥就可以进行实际接口调用实现扫码登录了。
一、前端部分
构造扫码登录页面(这里我使用的是方式二)
Web系统可以通过两种方式实现政务钉钉扫码登录。
方式一 使用政务钉钉提供的扫码登录页面
在企业Web系统里,用户点击使用钉钉扫码登录,第三方Web系统跳转到如下地址:
https://login.dg-work.cn/oauth2/auth.htm?response_type=code&client_id=应用标识&redirect_uri=回调地址&scope=get_user_info&authType=QRCODE
URL中的client_id和redirect_uri两个参数的值填入第三方web系统的应用标识和回调地址。政务钉钉用户扫码登录并确认后,会302到你指定的redirect_uri,并向url参数中追加临时授权码code(此code非authcode)及state两个参数。
注意事项:
参数"redirect_uri=回调地址"涉及的域名,需和创建扫码登录应用授权时填写的回调域名一致,否则会提示无权限访问。
生成二维码大小固定为200*200px,不支持修改。
方式二 支持网站将政务钉钉登录二维码内嵌到自己页面中
步骤1:在页面中通过iframe嵌入页面
通过方式一构造的地址增加embedMode=true的参数
https://login.dg-work.cn/oauth2/auth.htm?response_type=code&client_id=应用标识&redirect_uri=回调地址&scope=get_user_info&authType=QRCODE&embedMode=true
注意:这里的应用标识就是申请的扫码登录组件的应用标识。
回调地址是需要后端自己定义:即第三方 web 系统对应的地址进行相应的修改,一般是 http://服务器 ip: 端口/dist/empty.html#(后面路径根据实际进行修改即可)。
注意:浙政钉实际是限制域名,所以这里可能需要将 ip 换成域名,域名要进行申请。
步骤2:扫码成功后需要在页面中监听扫码结果
<script type="application/javascript"> window.addEventListener('message', function(event) { // 这里的event.data 就是登录成功的信息 // 数据格式:{ "code": "aaaa", "state": "bbbb" } alert(JSON.stringify(event.data)); });</script>
注意:生成二维码大小固定为200*200px,不支持修改。
各环境域名/登录域名
环境 | 开放平台域名(调接口使用) | 登录域名(构造登录页面) |
Saas | openplatform.dg-work.cn | login.dg-work.cn |
浙政钉 | openplatform-pro.ding.zj.gov.cn (域名对应政务外网IP:59.202.52.1) | login-pro.ding.zj.gov.cn (域名对应政务外网IP:59.202.52.68) |
获取应用access_token
获取access_token,请参考获取access_token。
注意请使用扫码应用的ak/sk获取access_token。
获取授权用户的个人信息
服务端通过临时授权码获取授权用户的个人信息
请求方式:POST(HTTPS)
接口名
/rpc/oauth2/getuserinfo_bycode.json
注意:请使用接口域名调用接口,不能使用登录域名调接口。
相关域名参照:各环境接口域名/登录域名
请求参数
参数 | 参数类型 | 必须 | 说明 |
access_token | String | 是 | 调用接口凭证,应用access_token |
code | String | 是 | 用户授权的临时授权码code,只能使用一次;在前面步骤中跳转到redirect_uri时会追加code参数 |
返回结果
{ "success":true, "content":{ "data":{ "accountId":100135, "lastName":"俊锋", "clientId":"mozi-buc-sso", "realmId":12371, "tenantName":"租户2", "realmName":"租户2", "namespace":"local", "tenantId":12371, "nickNameCn":"俊锋", "tenantUserId":"12371$100135", "account":"admin2" }, "success":true, "responseMessage":"成功", "responseCode":"0" }}
注:如果是超管账号调用该接口返回结果中无employeeCode,普通账号调用该接口有。
返回参数
参数 | 说明 |
accountId | 账号id |
realmId | 租户id |
realmName | 租户名 |
lastName | 姓名 |
nickNameCn | 昵称 |
account | 登录账号 |
employeeCode | 人员code |
tenantUserId | 员工在当前企业内的唯一标识 |
namespace | 账号类型标识 |
clientId | 应用标识 |
tenantId | 租户id |
tenantName | 租户名 |
二、后端
拿到对应的 appkey 以及密钥我们根据钉钉官方文档中的记录,进行接口调用测试。
例如:先获取 token,再根据获取的 token 和 code 获取用户信息,最后实现二维码登录逻辑。
先调用获取 token 接口, 拿到入参 appkey和密钥进行测试,如下:
官方文档:
ExecutableClient executableClient =ExecutableClient.getInstance();
executableClient.setAccessKey("appkey");
executableClient.setSecretKey("appsecrt");
executableClient.setDomainName("不同环境对应不同域名");
executableClient.setProtocal("https");
executableClient.init();
//executableClient要单例,并且使用前要初始化,只需要初始化一次
String api = "/gettoken.json";
GetClient getClient = executableClient.newGetClient(api);
//设置参数
getClient.addParameter("appkey", "37affba10137489c9cc8812b6b19590000003501");
getClient.addParameter("appsecret", "37affba10137489c9cc8812b6b19590000003501");
//调用API
String apiResult = getClient.get();
System.out.println(apiResult);
正确返回结果:
{
"success":true,
"content":{
"data":{
"accessToken":"c139fe44362f41b6b84862ec82ab84d9",
"expiresIn":"7200"
},
"requestId":"df04428415724925400701038d663a",
"responseMessage":"OK",
"responseCode":"0",
"success": true
}
}
注意:参考官方文档,一定要把对应参数写准确,appKey 和密钥最好进行复制黏贴,有大小写且很长,不要手敲,容易出错!!!
executableClient要单例,并且使用前要初始化,只需要初始化一次.
这是我的获取 token 接口 :
1.相关配置文件,这里实际修改你自己的 appKey 和密钥,注意:一定要写正确,不然会报白名单错误。
@ToString
public class DingDingConfig {
// appKey
public static String appKey = "";
// 浙政钉域名 openplatform-pro.ding.zj.gov.cn
public static String domainName = "";
// appSecret
public static String appSecret = "";
public static String otherAppKey = "";
public static String otherAppSecret = "";
}
public String getAccessToken() {
ExecutableClient executableClient = ExecutableClient.getInstance();
executableClient.setDomainName(DingDingConfig.domainName);
executableClient.setProtocal("https");
executableClient.setAccessKey(DingDingConfig.appKey);
executableClient.setSecretKey(DingDingConfig.appSecret);
executableClient.init();
String api = "/gettoken.json";
GetClient getClient = executableClient.newGetClient(api);
// 调用API
String apiResult = getClient.get();
log.info("获取浙政钉token:{}", apiResult);
// 处理返回结果
JSONObject jsonObject = JSONObject.parseObject(apiResult);
String token = null;
if (jsonObject.getBoolean("success")) {
token = jsonObject.getJSONObject("content").getJSONObject("data").getString("accessToken");
}
return token;
}
获取用户个人信息:这里我们可以拿到返回结果中所需要的数据。比如这里我需要 accountId 和 tenantId。(参考钉钉文档)
/**
* 获取授权用户的个人信息
*
* @param code
* @return
*/
public Map<String, Object> getUserInfoByCode(String code) {
Map<String, Object> result = new HashMap<>();
String accountId = null;
String tenantId = null;
try {
String accessToken = getAccessToken();
ExecutableClient executableClient = ExecutableClient.getInstance();
executableClient.setDomainName(DingDingConfig.domainName);
executableClient.setProtocal("https");
executableClient.setAccessKey(DingDingConfig.appKey);
executableClient.setSecretKey(DingDingConfig.appSecret);
executableClient.init();
String api = "/rpc/oauth2/getuserinfo_bycode.json";
PostClient getClient = EnumSingleton.INSTANCE.getIntance().newPostClient(api);
// 设置参数
getClient.addParameter("access_token", accessToken);
getClient.addParameter("code", code);
// 调用API
String apiResult = getClient.post();
log.info("apiResult:" + apiResult);
// 处理返回结果
Map<String, Object> map = (Map<String, Object>) JSONObject.parse(apiResult);
if (map != null) {
Map<String, Object> content = (Map<String, Object>) map.get("content");
if (content != null) {
Map<String, Object> data = (Map<String, Object>) content.get("data");
if (data != null) {
accountId = data.get("accountId").toString();
tenantId = data.get("tenantId").toString();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
result.put("accountId", accountId);
result.put("tenantId", tenantId);
return result;
}
上面接口测通后,我们即可以实现扫码登录逻辑,具体实现实际出发,根据当前需求进行相应的开发,调用浙政钉接口获取需要的数据。