企业内部应用实现钉钉免登录及登录成功后推送消息

2 篇文章 0 订阅

首先要通过钉钉开放平台创建H5微应用,得到企业id(CorpId),和H5微应用凭证:微应用的ID(AgentId)、微应用的唯一标识key(AppKey)、密钥(AppSecret)。

钉钉开放平台链接
https://open-dev.dingtalk.com

钉钉免登录流程:
1、前端通过CorpId获取免登授权码code;
2、后端通过AppKey和AppSecret获取access_token;
3、使用免登授权码code和access_token去获取用户userid;
4、通过access_token和userid去获取用户详情userinfo;
5、拿userinfo信息去和登录用户去比较,如果一致,则免登录成功。

注意事项
因为是企业内部应用免登录,所以不需要鉴权。免登授权码code每次请求返回的数据都不一样,请求一次的时效是5分钟,access_token有效期7200秒,自动续期。

前端代码

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<script src="/webjars/jquery/jquery.min.js"></script>
	<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>
	<!-- 引入JSAPI -->
	<script src="https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js"></script>
	<title>企业内部应用钉钉免登录</title>
</head>
<script type="text/javascript">

	function relevance(){
		// 此方法必须在钉钉环境下才能执行
		dd.ready(function() {
			// 获取免登授权码code
			dd.runtime.permission.requestAuthCode({
				corpId : "dingxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" , // 企业id
				onSuccess : function(result) {
					var code = result.code;
					getUserInfo(code); //通过该code可以获取用户身份
				},
				onFail : function(err) {
					alert('获取授权码失败: ' + JSON.stringify(err));
				}
			});
		});
	}

	function getUserInfo(code) {
		$.ajax({
			type : "GET",
			url : "/ddUser/getUserInfo?code=" + code,
			contentType : "application/json;charset=utf-8",
			success : (function(res) {
				if(res.isLogin){
					alert("登陆成功!")
				}else{
					alert("登录失败!");
				}
			}),
			error: (function (err) {
				alert("调用getUserInfo失败 err为:" + JSON.stringify(err));
			}),
		});
	}
</script>
<body style="padding-top: 52px;text-align: center;">
	<button onclick="relevance()">立即绑定</button>
</body>
</html>

后端代码

将钉钉开放平台中得到的CorpId,AgentId,AppKey,AppSecret放到application.yml里面。

azure:
	corpid: dingxxxxxxxxxxxxxxxxxxxxxxxxxxx
	appkey: dingxxxxxxxxxxxxxxx
	appsecret: RVYcJvDtymXWsD9lwXBJRd1qKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	agentid: 9718xxxxx

创建工具类

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class HttpHelper {

	@Value("${azure.corpid}")
    private static String corpid;

    @Value("${azure.appsecret}")
    private static String appsecret;

    @Value("${azure.agentid}")
    private static String agentid;

    @Value("${azure.appkey}")
    private static String appkey;

	public static JSONObject httpGet(String url){
        //创建httpClient
        CloseableHttpClient httpClient= HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);                             //生成一个请求
        RequestConfig requestConfig = RequestConfig.custom().         //配置请求的一些属性
                setSocketTimeout(2000).setConnectTimeout(2000).build();
        httpGet.setConfig(requestConfig);                             //为请求设置属性
        CloseableHttpResponse response = null;
        try {
            response=httpClient.execute(httpGet);
            //如果返回结果的code不等于200,说明出错了
            if (response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();                 //reponse返回的数据在entity中
            if(entity!=null){
                String resultStr= EntityUtils.toString(entity,"utf-8");//将数据转化为string格式
                JSONObject result= JSONObject.parseObject(resultStr);  //将结果转化为json格式
                if(result.getInteger("errcode")==0){                  //如果返回值得errcode值为0,则成功
                    //移除一些没用的元素
                    result.remove("errcode");
                    result.remove("errmsg");
                    return result;                                    //返回有用的信息
                }else{                                                 //返回结果出错了,则打印出来
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("ErrorCode:"+errCode+"ErrorMsg"+errMsg);
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

	// 调用httpGet方法获得access_token的代码实现:
    public static String getAccess_Token(String appkey,String appsecret){
        String url="https://oapi.dingtalk.com/gettoken?"+"appkey="+appkey+"&appsecret="+appsecret;
        JSONObject res= HttpHelper.httpGet(url);                      //将httpGet方法封装在HttpHelper类中
        String access_token="";
        if(res!=null){
            access_token=res.getString("access_token");
        }else{
            new Exception("获取token异常");
        }
        return access_token;
    }

	// 执行POST请求(如果免登录成功后不需要推送钉钉消息,则不需要此方法)
	public static String httpPost(String url, Map<String, Object> params, String encoding) throws Exception {
		String result = "";
		// 创建默认的httpClient实例.
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建httppost
		HttpPost httppost = new HttpPost(url);
		//参数
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		if (params != null) {
		    Set<String> keys = params.keySet();
		    for (String key : keys) {
		        formparams.add(new BasicNameValuePair(key, params.get(key).toString()));
		    }
		}
		UrlEncodedFormEntity uefEntity;
		try {
		    uefEntity = new UrlEncodedFormEntity(formparams, encoding);
		    httppost.setEntity(uefEntity);
		    CloseableHttpResponse response = httpclient.execute(httppost);
		    try {
		        Header[] headers = response.getAllHeaders();
		        for (Header header : headers) {
		            log.debug(header.getName() + "-->" + header.getValue());
		        }
		        HttpEntity entity = response.getEntity();
		        if (entity != null) {
		            result = EntityUtils.toString(entity, encoding);
		        }
		    } finally {
		        response.close();
		    }
		} catch (IOException e) {
		    throw e;
		} finally {
		    // 关闭连接,释放资源
		    try {
		        httpclient.close();
		    } catch (IOException e) {
		    }
		}
			return result;
		}
}

Controller层

import com.alibaba.fastjson.JSONObject;
import com.totyu.mmc.controller.dingding2.model.contact.User;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/ddUser")
@Api(value = "/ddUser")
public class DingdingController {

	@Value("${azure.corpid}")
    private String corpid;

    @Value("${azure.appkey}")
    private String appkey;

    @Value("${azure.appsecret}")
    private String appsecret;

    @Value("${azure.agentid}")
    private String agentid;

	private static final String GET_USERINFO_BYCODE_URL="https://oapi.dingtalk.com/user/getuserinfo?access_token=ACCESSTOKEN&code=CODE";
	
	private static final String GET_USER_URL="https://oapi.dingtalk.com/user/get?access_token=ACCESSTOKEN&userid=USERID";

	/** 根据免登授权码Code查询免登用户
     * @param code
     */
    @GetMapping("/getUserInfo")
    public JSONObject getUserInfo(@RequestParam("code") String code) {
        JSONObject jsonObject = new JSONObject();
        try {
            // 获取access_token
            String accessToken = HttpHelper.getAccess_Token(appkey,appsecret);

            // UserId的URL
            String getUserIdURL = GET_USERINFO_BYCODE_URL.replace("ACCESSTOKEN", accessToken).replace("CODE", code);
            // 发起GET请求,获取返回结果
            jsonObject = HttpHelper.httpGet(getUserIdURL);
            String userid = (String)jsonObject.get("userid");

            // User详情的URL
            String getUserURL = GET_USER_URL.replace("ACCESSTOKEN", accessToken).replace("USERID", userid);
            // 发起GET请求,获取返回结果
            jsonObject = HttpHelper.httpGet(getUserURL);

            // 钉钉发送消息给用户
            sendMessage(accessToken,userid,(String)jsonObject.get("name"));
            jsonObject.put("isLogin",true);

        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("isLogin",false);
        }
        return jsonObject;
    }

	// 钉钉发送消息给用户
    private void sendMessage(String token, String userid, String userName) throws Exception{
        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);
        map.put("userid_list", userid);
        map.put("to_all_user", false);
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
        String date = dateformat.format(new Date());
        String content = "用户"+userName+"在"+ date +"时成功登录xxx!";
        String msg = "{\"msgtype\":\"text\",\"text\":{\"content\":"+"\""+content+"\""+"}}";
        JSONObject jsonObj = JSONObject.parseObject(msg);
        map.put("msg",jsonObj);
        HttpHelper.httpPost(messageUrl,map,"UTF-8");
    }
}

到此就可以实现免登录钉钉了,业务层可以根据需求自己加。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现消息,可以使用提供的开放平台API,具体步骤如下: 1. 首先在开放平台注册应用,获得相应的AppKey和AppSecret。 2. 在应用中创建一个机器人,并获得机器人Webhook地址。 3. 使用Java的HttpURLConnection或者HttpClient等工具,向机器人Webhook地址发POST请求,请求内容为JSON格式的消息。 4. 在请求头中添加Content-Type和Charset等必要的参数。 5. 如果需要对消息进行加密,可以使用提供的加密算法进行加密。 6. 会对收到的消息进行安全校验,如果校验失败则无法正常消息。 7. 如果成功会返回JSON格式的响应,可以根据响应结果判断是否成功。 下面是一个示例代码: ``` import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class DingTalkUtil { private static final String WEBHOOK_TOKEN = "机器人Webhook地址"; private static final String CONTENT_TYPE = "application/json"; private static final String CHARSET = "UTF-8"; public static void sendTextMessage(String message) { try { URL url = new URL(WEBHOOK_TOKEN); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", CONTENT_TYPE); conn.setRequestProperty("Charset", CHARSET); OutputStream os = conn.getOutputStream(); os.write(message.getBytes(CHARSET)); os.flush(); os.close(); int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 处理成功的逻辑 } else { // 处理失败的逻辑 } conn.disconnect(); } catch (Exception e) { // 处理异常情况 } } } ``` 其中,sendTextMessage方法可以用来向机器人发文本消息。需要注意的是,还支持发Markdown格式和ActionCard格式的消息,具体使用方法可以参考开放平台文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值