• 对接专有钉钉(浙政钉)登陆步骤


    背景

    因为项目需要对接浙政钉,我想应该和之前对接阿里云的钉钉登陆钉钉登陆类似,就上网搜索看看,出现了个专有钉钉的概念,就一时间搞不清楚,钉钉,专有钉钉,浙政钉的区别,后续稍微理解了点,不一定完全正确哈。 可给大家做参考。
    浙政钉: 线上环境使用的,一般是政府用的比较多。 在政务外网
    钉钉:一般是企业用的,公网使用。
    专有钉钉: 浙政钉的公网测试版本。

    流程

    参考链接中有流程,我这面的话在贴一张流程图
    在这里插入图片描述

    准备工作

    创建应用

    登陆专有钉钉,这里的话,如果是首次的话我感觉比较麻烦,没有注册之类的。 我都是让同事把我加到他的测试组织中的,就跳过比较麻烦的点,所以我就不清楚具体怎么注册了。 登陆之后创建应用
    根据自己的需求来选择,这里我选择了扫码登陆。
    在这里插入图片描述

    在这里插入图片描述

    设置回调

    应用创建成功之后点击详情
    在这里插入图片描述
    凭证与基础信息 中的 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就可以了。
    在这里插入图片描述
    剩下的二维码和对接就交给前端的同事来对接就好了。

    参考链接

    专有钉钉

  • 相关阅读:
    别再说你不知道分布式事务了
    Servlet urlPatterns配置
    字典组件(前端使用)
    Html编写发射粒子爱心
    含文档+PPT+源码等]精品基于SSM的物流管理系统[包运行成功]Java毕业设计SSM项目源码快递管理系统
    黑马程序员微服务 分布式搜索引擎3
    window拖拽操作的实现
    10.网络编程套接字Socket
    大数据开发,Hadoop Spark太重?你试试esProc SPL
    浅析C++内存布局
  • 原文地址:https://blog.csdn.net/qq_37716298/article/details/139442684