背景
因为项目需要对接浙政钉,我想应该和之前对接阿里云的钉钉登陆钉钉登陆类似,就上网搜索看看,出现了个专有钉钉的概念,就一时间搞不清楚,钉钉,专有钉钉,浙政钉的区别,后续稍微理解了点,不一定完全正确哈。 可给大家做参考。
浙政钉: 线上环境使用的,一般是政府用的比较多。 在政务外网
钉钉:一般是企业用的,公网使用。
专有钉钉: 浙政钉的公网测试版本。
流程
参考链接中有流程,我这面的话在贴一张流程图
准备工作
创建应用
登陆专有钉钉,这里的话,如果是首次的话我感觉比较麻烦,没有注册之类的。 我都是让同事把我加到他的测试组织中的,就跳过比较麻烦的点,所以我就不清楚具体怎么注册了。 登陆之后创建应用
根据自己的需求来选择,这里我选择了扫码登陆。
设置回调
应用创建成功之后点击详情
凭证与基础信息 中的 App Key 和App Secret 这二我们后端是需要使用的,先简单看一下。到时候可以设置成配置。
设置回调地址
回调地址的作用:可参考在流程中政务登陆服务给我们后端临时授权码的那一步。
后端实现
引入第三方jar
<dependency>
<groupId>com.alibaba.zwdd</groupId>
<artifactId>zwdd-sdk</artifactId>
<version>1.2.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/zwdd-sdk-java-1.2.0.jar</systemPath><!--路径-->
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
这个zwdd-sdk-java-1.2.0.jar没有在中央仓库中,需要自己下载引入。
下载链接
引入也很简单,在项目目录创建一个lib文件夹,放进去就可以了。上面有写好怎么引入本地包的。
代码实现
这里我们就实现二个接口,一个是获取token 一个是获取用户信息。
Service接口
public interface ZheJiangDingTalkService {
/**
* 获取token
* @param
* @return
*/
String getToken();
/**
* 获取用户信息
* @param authCode
* @return
*/
ZheJiangUserInfoApiResult getUserInfo(String accessToken,String authCode);
}
Service实现
Service
public class ZheJiangDingTalkServiceImpl implements ZheJiangDingTalkService {
@Resource
private DingDingProperties dingDingProperties;
@Override
public String getToken() {
try {
ExecutableClient executableClient = init();
return getToken(executableClient);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getToken(ExecutableClient executableClient) {
try {
//executableClient保证单例
PostClient intelligentGetClient = executableClient.newPostClient("/gettoken.json");
OapiGettokenJsonRequest oapiGettokenJsonRequest = new OapiGettokenJsonRequest();
//应用的唯一标识key
oapiGettokenJsonRequest.setAppkey(dingDingProperties.getAppKey());
//应用的密钥
oapiGettokenJsonRequest.setAppsecret(dingDingProperties.getAppSecret());
//获取结果
String apiResult = intelligentGetClient.post();
Type type = new TypeToken<ZheJiangTokenApiResult<ZheJiangTokenBaseApiResult>>() {}.getType();
ZheJiangTokenApiResult<ZheJiangTokenBaseApiResult> tokenApiResult = GsonUtil.stringToBean(apiResult, type);
if (tokenApiResult.success()) {
ZheJiangTokenBaseApiResult.ZheJiangTokenApiResult resultData = tokenApiResult.getContent().getData();
String accessToken = resultData.getAccessToken();
return accessToken;
}
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public ZheJiangUserInfoApiResult getUserInfo(String accessToken,String code) {
ExecutableClient init = init();
IntelligentGetClient intelligentPostClient = init.newIntelligentGetClient("/rpc/oauth2/getuserinfo_bycode.json");
OapiRpcOauth2GetuserinfoBycodeJsonRequest oapiRpcOauth2DingtalkAppUserJsonRequest = new OapiRpcOauth2GetuserinfoBycodeJsonRequest ();
//登录access_token
oapiRpcOauth2DingtalkAppUserJsonRequest.setAccess_token(accessToken);
//临时授权码 //回调的码
oapiRpcOauth2DingtalkAppUserJsonRequest.setCode(code);
//获取结果
OapiRpcOauth2GetuserinfoBycodeJsonResponse apiResult = intelligentPostClient.get(oapiRpcOauth2DingtalkAppUserJsonRequest);
String content = apiResult.getContent();
Type type = new TypeToken<ZheJiangTokenApiResult<ZheJiangBaseApiResult<ZheJiangUserInfoApiResult>>>() {}.getType();
ZheJiangTokenApiResult<ZheJiangBaseApiResult<ZheJiangUserInfoApiResult>> tokenApiResult = GsonUtil.stringToBean(content, type);
if(tokenApiResult.success()) {
return tokenApiResult.getContent().getData();
}
return null;
}
private ExecutableClient init(){
ExecutableClient executableClient =ExecutableClient.getInstance();
executableClient.setAccessKey(dingDingProperties.getAppKey());
executableClient.setSecretKey(dingDingProperties.getAppSecret());
executableClient.setDomainName(dingDingProperties.getDomainName());
executableClient.setProtocal("https");
executableClient.init();
return executableClient;
}
}
这里我们使用了Gson和创建了几个对象,这里的代码的话,我简单贴一下,看你们是否愿意使用,不愿意的话,可自己写的。
工具类
public class GsonUtil {
/**
* 不用创建对象,直接使用Gson.就可以调用方法
*/
private static Gson gson = null;
private static JsonParser jsonParser = null;
/**
* 判断gson对象是否存在了,不存在则创建对象
*/
static {
//gson = new Gson();
// 当使用GsonBuilder方式时属性为空的时候输出来的json字符串是有键值key的,显示形式是"key":null,而直接new出来的就没有"key":null的
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
if(jsonParser == null ){
jsonParser = new JsonParser();
}
}
private GsonUtil() {}
}
/**
* 将json转成特定的cls的对象
* @param gsonString
* @param cls
* @return
*/
public static <T> T stringToBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
//传入json对象和对象类型,将json转成对象
t = gson.fromJson(gsonString, cls);
}
return t;
}
public static <T> T stringToBean(String gsonString, Type type) {
T t = null;
if (gson != null) {
//传入json对象和对象类型,将json转成对象
t = gson.fromJson(gsonString, type);
}
return t;
}
}
@Component
@ConfigurationProperties(prefix = "dingtalk.msg")
@Setter
@Getter
public class DingDingProperties {
public String appKey = "xx";
public String appSecret = "xxx";
private String domainName="openplatform.dg-work.cn";
}
实体
@Setter
@Getter
@ToString
public class ZheJiangBaseApiResult<T> {
private T data;
private boolean success;
private String requestId;
private String responseMessage;
private String responseCode;
private String bizErrorCode;
public boolean isSuccess(){
return ("0").equals(this.bizErrorCode);
}
}
@Setter
@Getter
@ToString
public class ZheJiangTokenApiResult<T> {
private T content;
private String bizErrorCode;
private boolean success;
public boolean success(){
return ("0").equals(this.bizErrorCode) || success;
}
}
@Setter
@Getter
@ToString
public class ZheJiangTokenBaseApiResult {
private ZheJiangTokenApiResult data;
private boolean success;
private String requestId;
private String responseMessage;
private String responseCode;
private String bizErrorCode;
@Setter
@Getter
public class ZheJiangTokenApiResult {
private int expiresIn;
private String accessToken;
}
}
@Setter
@Getter
@ToString
@NoArgsConstructor
public class ZheJiangUserInfoApiResult {
public Integer accountId;
private boolean success;
public String lastName;
public String clientId;
public Integer realmId;
public String realmName;
public String namespace;
public String nickNameCn;
public String tenantUserId;
public String account;
public String employeeCode;
}
额外的pom文件
<!-- gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
注意事项
DingDingProperties 中的domainName 记得正式环境更改成openplatform-pro.ding.zj.gov.cn
让客户提供下正式环境下的 app-key和app-secret就可以了。
剩下的二维码和对接就交给前端的同事来对接就好了。