用java实现“钉钉微应用,免登进入某H5系统首页“功能”

一、前言

哈哈,这是我的第一篇博客。

先说一下这个小功能的具体场景:

用户登录钉钉app,点击微应用,获取当前用户的信息,与H5系统的数据库的用户信息对比,如果存在该用户,则点击后直接进入H5系统的首页,否则显示“您无权限”。

补充:又加了一个小需求,就是免登成功,会给该用户发条消息

我是参考钉钉开发文档实现的这个小功能,文档地址:https://ding-doc.dingtalk.com/doc#/serverapi2/clotub

二、准备工作

需要创建一个微应用:https://open-dev.dingtalk.com

1.是在企业内部开发中创建H5微应用,不是第三方企业应用中

企业内部开发:企业内部开发是指“开发企业内部应用”供企业内部的人员使用。企业可以选择由企业内部的开发者进行开发,或者由企业授权定制服务商进行开发。

第三方企业应用:第三方企业应用开发,是指开发者以钉钉、企业之外的第三方身份,基于钉钉的开放能力开发应用,并提供给钉钉上的其他组织使用。(哈哈,这个区别我是直接copy文档中的)

2.H5工程中,创建的一个前端页面ddNoLogin.html(哈哈,这个起名有点中文式英语,因为我没有找到合适的英文单词):

该页面是用来获取免登授权码,然后把该code传递给后台接口的。

3.填写公司服务器的公网IP

可以敲命令查看该ip:curl ifconfig.me

4.微应用创建好,会生成三个参数,

agentId、appKey、appSecret

外加一个corpId(钉钉开发者平台的首页中有显示),这四个参数值是固定的,后续开发需用

5.接口权限

高级权限-企业通讯录中的接口都需要给开通

6.最后发布应用

三、功能开发

哈哈,要开始敲代码了

1.获取免登授权码code

这里调用的是钉钉JS-API中的方法,本功能调用的方法是不需要鉴权的,如果需要鉴权,则还需先dd.config。

关于功能方法是否需要鉴权,可以去查看JSAPI总览

ddNoLogin.html:

<!DOCTYPE html>
<html>
<head>
    <title>微应用登陆</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1 user-scalable=0" />
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script>
</head>
<body>
<div id="ddNoLogin"></div>
<script type="text/javascript">
        dd.ready(function() {
		//1.获取免登授权码code
		dd.runtime.permission.requestAuthCode({
			corpId : corpId ,  //企业id
			onSuccess : function(result) {
				var code = result.code;
				getUserInfo(code);   //通过该code可以获取用户身份
			},
			onFail : function(err) {
				alert(‘出错了, ‘ + err);
			}
		});
	});
        function getUserInfo(code) {
		$.ajax({
			type : "GET",
			url : "/xxx/noLogin?code=" + code,
			async : false,
			dataType : ‘json‘,
			contentType : "application/json;charset=utf-8",
			success : (function(res) {
				if(res.code == "0000"){
			           window.location.href = ‘/#/xxxxx‘;
                                }else{
                                   $(‘#ddNoLogin‘).html(res.msg);
                                }
			}),
		});
	}
</script>
</body>
</html>

获取code的实现是需要用前端JS去写的

2.获取access_token

钉钉提供了开放的api后台接口,这里通过appkey和appsecret获取token,请求路径:https://oapi.dingtalk.com/gettoken?appkey=key&appsecret=secret

该token有效期是2个小时,有效期内重复获取,会返回相同结果,并自动续期,

故这里我的实现是:定时刷新token,每隔1小时50分钟去获取钉钉的token,并缓存到redis中(我把钉钉的相关配置都放入到application.yml中了)

DdTokenTask.java:

/**
 * 定时获取钉钉的token
 */
@Component
@EnableScheduling
public class DdTokenTask {

    @Autowired
    private JedisClient jedisClient;

    public static final long cacheTime = 1000 * 60 * 55 * 2;//1小时50分钟
    @Value("${dtalk.tokenUrl}")
    private String tokenUrl;
    @Value("${dtalk.app.key}")
    private String appKey;
    @Value("${dtalk.app.secret}")
    private String appSecret;
    @Value("${dtalk.redisTokenKey}")
    private String tokenKey;
    @Value("${dtalk.taskRun}")
    private String taskRun;

    /**
     * 每隔1小时50分钟获取钉钉的access_token
     */
    @Scheduled(fixedRate = cacheTime)
    @Async
    public void getDdTokenTask(){
        if("true".equals(taskRun)){
            //刷新
            System.out.println("--->>>>>-------------获取钉钉token的定时任务开始了:"+ DateUtil.formatDateToString(new Date(), "HH:mm:ss"));

            String accessTokenUrl = tokenUrl + "?appkey=" + appKey + "&appsecret=" + appSecret;
            //访问获取access_token   有效期是2小时
            String accessToken = JsonUtil.getJsonNode(HttpUtil.doGet(accessTokenUrl)).get("access_token").asText();
            //放入到redis中
            jedisClient.set(tokenKey, accessToken);

            System.out.println("--->>>>>-------------获取钉钉token的定时任务结束了,token:"+accessToken);
        }
    }

    /*private String getAccessToken(){
        //需引入SDK,公司私服没有
        DefaultDingTalkClient client = new
        DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey("appkey");
        request.setAppsecret("appsecret");
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return "";
    }*/

}

(哈哈,其实文档中提供了钉钉SDK的java写法,不过公司私服没有该SDK,所以我就直接用htttp请求了)

3.获取用户userid

通过免登授权码和access_token获取用户的userid,请求路径:https://oapi.dingtalk.com/user/getuserinfo?access_token=access_token&code=code

4.获取用户详情

请求路径:https://oapi.dingtalk.com/user/get?access_token=ACCESS_TOKEN&userid=shaocui

会返回用户的姓名、手机号等所有信息

DdLoginController.java:

@RestController
@RequestMapping("/ddUser")
@Api(value = "/ddUser", description = "钉钉H5微应用登录", tags = {"DdLoginController"})
public class DdLoginController {

    @Autowired
    private JedisClient jedisClient;

    @Value("${dtalk.userUrl}")
    private String userUrl;
    @Value("${dtalk.userDetailUrl}")
    private String userDetailUrl;
    @Value("${dtalk.redisTokenKey}")
    private String tokenKey;
    @Value("${dtalk.agentId}")
    private Integer agentId;

    @GetMapping("/noLogin")
    @ApiOperation( "钉钉免登")
    @ApiImplicitParam(paramType = "query", name = "code", value = "免登授权码", dataType = "String")
    public WebResponse noLogin(@RequestParam("code") String code, HttpServletResponse response){
        //2.获取access_token
        String accessToken = jedisClient.get(tokenKey);

        //3.获取用户userid
        String userIdUrl =userUrl + "?access_token=" + accessToken + "&code=" + code;
        //访问获取userid
        JsonNode user = JsonUtil.getJsonNode(HttpUtil.doGet(userIdUrl));
        if(user.get("errcode").asInt() != 0){
            //有些公司的公网ip不固定,导致微应用中设置的不对,这里就会报错
            return WebResponse.resFail(user.get("errmsg").asText());
        }
        String userId = user.get("userid").asText();

        //4.获取用户详情  手机号
        String userInfoUrl = userDetailUrl + "?access_token=" + accessToken + "&userid=" + userId;
        //访问获取mobile
        JsonNode userInfo = JsonUtil.getJsonNode(HttpUtil.doGet(userInfoUrl));
        String mobile = userInfo.get("mobile").asText();

        System.out.println("钉钉用户的手机号:"+mobile);

        //通过手机号获取该用户
        SysUser sysUser = 。。。。。;
        if(sysUser == null){
            //不存在该用户
            return WebResponse.resFail("您无权限访问", null);
        }

        。。。。。。

        //钉钉发送免登成功消息给用户
        sendMessage(accessToken, userId, userInfo.get("name").asText());

        return WebResponse.resSuccess("免登成功", loginUserInfo);
    }

    //钉钉发送消息给用户
    private void sendMessage(String token, String userId, String userName){
        String messageUrl = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token="+token;
        Map<String, Object> map = new HashMap<>();
        map.put("agent_id", agentId.longValue());
        map.put("userid_list", userId);
        map.put("to_all_user", false);
        String content = "用户"+userName+"在"+ DateUtil.formatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss")+"时成功登录xxH5端,并进入到xxx页面";
        String msg = "{\"msgtype\":\"text\",\"text\":{\"content\":"+"\""+content+"\""+"}}";
        JSONObject jsonObj = JSONObject.parseObject(msg);
        map.put("msg",jsonObj);

        HttpUtil.doPost(messageUrl, map, "UTF-8", 20000, null);
    }
}

(哈哈,那个。。。。。处的代码是实现系统认证成功后的具体操作,故这里省略)

到此钉钉免登就实现了,然后免登成功后给用户发送消息

5.工作通知消息

POST请求,请求路径:https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=ACCESS_TOKEN

请求体{agent_id、userid_list、dept_id_list、to_all_user、msg}

注意:

给同一个用户发送相同的内容,一天只能发一次;发送不同的内容,一天可以500次,

故这里我在发送的消息中添加了当前时间。

(哈哈,一些细节的东西我都写在代码的注释里了,最后发现这个小功能好像就一点点代码量)

原文地址:https://www.cnblogs.com/muxisc/p/11613628.html

时间: 2024-09-29 23:38:45

用java实现“钉钉微应用,免登进入某H5系统首页“功能”的相关文章

.NET平台下,钉钉微应用开发之:获取userid

工作需求,开发钉钉微应用和小程序,之前有接触过支付宝小程序和生活号的开发,流程没有很大的差别,这里记录下我用ASP.NET MVC实现钉钉微应用的开发,并实现获取用户的userid.小弟我技术有限,本文中的一些命名或方法写的不好的,还请指点. 钉钉开发者平台上有各个平台的SDK,我也有下载对应的.NET版本的SDK,但是还没有全搞懂,我先用最土的办法:直接发起http请求,来获取我需要的数据,后面如果有时间我会把.NET的也补上. 1.注册钉钉微应用: 注册完成之后,继续完善下应用配置,如IP白

Java钉钉开发_02_免登授权(身份验证)(附源码)

源码已上传GitHub: https://github.com/shirayner/DingTalk_Demo 一.本节要点 1.免登授权的流程 (1)签名校验 (2)获取code,并传到后台 (3)根据code获取userid (4)根据userid获取用户信息,(此处可进行相应业务处理) (5)将用户信息传到前端,前端拿到用户信息,并做相应处理 2.计算签名信息(signature) 2.1 待签名参数 ticket jsapi_ticket nonceStr        随机字符串,随机

Java钉钉开发_03_通讯录管理之 人员管理 和 部门管理

一.本节要点 1.通讯录权限 ISV(应用服务商)默认无管理通讯录的权限,企业应用默认有所有通讯录权限. 2.数据传输格式—JSON 请参见: Java_数据交换_fastJSON_01_用法入门 二.代码实现 1.HTTP请求工具类—HttpHelper package com.ray.dingtalk.qy.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; impor

js api 实现钉钉免登

js api 实现钉钉免登,用于从钉钉微应用跳转到企业内部的oa,erp等,我刚刚实施完了我公司的这个功能,钉钉用起来还不错. 1 js api 实现钉钉免登,页面配置. <title>利用jsapi实现免登</title>     <script type="text/javascript" src="https://g.alicdn.com/ilw/ding/0.7.5/scripts/dingtalk.js" ></s

钉钉免登前端实现

1.需求:开发钉钉微应用,需要实现钉钉的免登陆功能. # 其实钉钉的文档中心还是很详细的,只是刚开始接触会一头雾水,所以花费了挺多时间....... ?什么是钉钉免登功能. ?企业应用免登开发授权流程. 2.这里借用钉钉官方的流程图,前端在这个过程中的职责,其实是从我标注的部分开始的~~~

移动端(钉钉微服务)webpack配置需要移除hash来解决应用更新后白屏的问题

钉钉微服务webpack配置调整方案 1: Vue CLI配置修改方法 a. 修改build下webpack.prod.config.js.去掉图中三处hash(.[chunkhash]): b. 修改build下webpack.base.config.js.去掉图中hash: 2: 非Vue CLI配置修改方法: 类似CLI,通常去除config文件中的output的filename和chunkFilename的hash值以及rules中对应的hash值. 原文地址:https://www.c

shell+钉钉机器人完成java程序中断后自启动和实时监控

java实时程序在运行过程中偶尔出现异常信息中断的情况,通过shell脚本即可完成自启动. 以下为监控一个实时的java程序的shell脚本. 通过每10秒检查一次java程序的进程,来判断程序是否处于运行中.如果未发现程序,则执行程序的启动脚本. 对于启动过程中的状态信息,会通过钉钉机器人实时发送到监控群中,让维护人员了解到程序的异常. 在脚本中通过maxRetry来设置最大尝试的次数. #!/bin/sh # 最大尝试次数 maxRetry=3 # 尝试次数计数器 retryTimes=0

钉钉扫码登录 java

java获取扫码登录后的钉钉id 从而可以查出员工具体信息 部门具体信息 1.注册钉钉企业账号 注册地址 https://oa.dingtalk.com/register.html 开发文档地址 https://open-doc.dingtalk.com/microapp/isv 注册完支行查看corpId corpSecret 创建扫码登录使用的app ID.appSecret 2.下载钉钉sdk (http://img.alicdn.com/top/i1/LB1l7mXv0knBKNjSZK

钉钉——第三方应用嵌入钉钉【微应用】

2017年做了一款移动端手机web系统,用于公司的内部使用,使用了jquery mobile前端框架和后端SSM. 2018年11月份,要求将这款系统嵌入到钉钉平台,实现免登录. 踩了一堆坑...阿里云社区的也是问题多,成功解答的少. 总结一下: 第三方应用嵌入钉钉,钉钉仅仅提供 dingtalk.js 来给我们dd对象,dd对象的生命周期函数中可以利用相关code对钉钉账户信息进行相关请求, 我只做了userid获取,其他免登陆的工作全是三方应用的编码,与钉钉无关. 问题一:签名不正确,报错5