最近有一个钉钉的项目,所以,接下来的日子里,我会把钉钉开发中遇到的问题都整理成博客,供大家参考。
钉钉开发者后台,添加好了小程序,需要提供一个回调URL地址,用于数据的同步。如下图
根据钉钉提供的demo,可以很方便的实现数据的加密和解密,一切进展非常顺利。但在获取POST密文过程中,遇到了一个问题。
钉钉推送过来有三个参数:signature, timestamp, nonce,还有一个消息体:encrypt,三个参数获取正常,就是在获取这个消息体时,一直出错,导致验证回调URL不成功。那么也就不能获取到相应的推送事件。
经过多方测试,无果,查了网上资料,无果,实在没有办法下,自己电脑做了个内网穿透,直接把回调URL地址设在本机,直接VS打开调试查找问题。
问题就出在这个读取的方法上,原本用stream.Read()一直出错,换成异步的,就成功了。
完整代码如下:
public Dictionary<String, String> Index(string signature, string timestamp, string nonce) { //获取三个参数 DingTalkEncryptor ding = new DingTalkEncryptor(vdsets.token,vdsets.encodingAesKey,vdsets.corpId); //接收encrypt参数 string encryptStr = GetPostParam(); ////解密内容 string plainText = ding.getDecryptMsg(signature, timestamp, nonce, encryptStr); Hashtable tb = (Hashtable)JsonConvert.DeserializeObject(plainText, typeof(Hashtable)); //获取事件 string eventType = tb["EventType"].ToString(); //下面是根据事件名称进行相应的业务处理 //返回success var msg = ding.getEncryptedMap("success"); return msg; } public string GetPostParam() { Stream stream = HttpContext.Request.Body; byte[] buffer = new byte[HttpContext.Request.ContentLength.Value]; stream.ReadAsync(buffer, 0, buffer.Length); string content = Encoding.UTF8.GetString(buffer); return content.ToString().Replace("{\"encrypt\":\"", "").Replace("\"}", ""); }
上面代码用到了钉钉提供的demo,下载地址:
GitHub - open-dingtalk/dingtalk-callback-Crypto: 钉钉回调加解密类库和对应demo