2020/07/08 PHP/Python/Java No Comments 钉钉注册回调常见问题解决_PHP环境 **基于官方开放平台提供的PHP Demo进行钉钉业务事件回调接口注册时常见问题及解决:** **1、注册业务事件回调接口请求参数配置说明** ```php call_back_tag:需要监听的事件类型,如:["bpms_task_change", "bpms_instance_change"] token:加解密需要用到的token,自定义 aes_key:数据加密密钥。用于回调数据的加密,长度固定为43个字符,从a-z, A-Z, 0-9共62个字符中选取,可以随机生成 url:接收事件回调的url,必须是公网可以访问的url地址 ``` **2、接收事件回调的url页面加解密配置说明-测试回调URL** ```php //企业内部应用开发可以忽略该项 define("CREATE_SUITE_KEY", "suite4xxxxxxxxxxxxxxx"); //套件key。企业内部应用开发请填写corpid define("SUITE_KEY", "dingxxxxxxxxxxxxxxxx"); //企业内部应用开发可以忽略该项 define("SUITE_SECRET", ""); //加解密需要用到的token,自定义,保持和注册业务事件回调接口register_call_back传递的token值相同即可 define("TOKEN", "123456"); //企业内部应用可以忽略该项 define("APPID", ""); //数据加密密钥。自定义,用于回调数据的加密,长度固定为43个字符,从a-z, A-Z, 0-9共62个字符中选取,可以随机生成。保持和注册业务事件回调接口register_call_back传递的AES_KEY值相同即可 define("ENCODING_AES_KEY", "6g5j67qlyl3zvetqxz9jiocdr586fn2zvjp78zls3il"); ``` **3、post请求头(不是json格式)/请使用json格式上传数据** ```php public function curl_post_json($url, $jsonStr){ $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($jsonStr) ) ); $reponse = curl_exec($ch); return json_decode($reponse,1); } PS:如提示post参数需要json类型,请对参数进行json_encode编码下 ``` **4、官方开放平台提供的PHP Demo:pkcs7Encoder.php文件修改** ```php function Prpcrypt($k) { $this->key = base64_decode($k . "="); } 修改为构造函数形式: function __construct($k){ $this->key = base64_decode($k . "="); } ``` **5、官方开放平台提供的PHP Demo:DingtalkCrypt.php文件修改** ```php class DingtalkCrypt { private $m_token; private $m_encodingAesKey; private $m_suiteKey; //注意这里修改为构造函数 function __construct($token, $encodingAesKey, $suiteKey) { $this->m_token = $token; $this->m_encodingAesKey = $encodingAesKey; $this->m_suiteKey = $suiteKey; } public function EncryptMsg($plain, $timeStamp, $nonce, &$encryptMsg) { $pc = new Prpcrypt($this->m_encodingAesKey); $array = $pc->encrypt($plain, $this->m_suiteKey); $ret = $array[0]; if ($ret != 0) { //return $ret; return ['ErrorCode'=>$ret, 'data' => '']; } if ($timeStamp == null) { $timeStamp = time(); } $encrypt = $array[1]; $sha1 = new SHA1; $array = $sha1->getSHA1($this->m_token, $timeStamp, $nonce, $encrypt); $ret = $array[0]; if ($ret != 0) { //return $ret; return ['ErrorCode'=>$ret, 'data' => '']; } $signature = $array[1]; $encryptMsg = json_encode(array( "msg_signature" => $signature, "encrypt" => $encrypt, "timeStamp" => $timeStamp, "nonce" => $nonce )); //return ErrorCode::$OK; return ['ErrorCode'=>ErrorCode::$OK, 'data' => $encryptMsg]; } public function DecryptMsg($signature, $timeStamp = null, $nonce, $encrypt, &$decryptMsg) { if (strlen($this->m_encodingAesKey) != 43) { //return ErrorCode::$IllegalAesKey; return ['ErrorCode'=>ErrorCode::$IllegalAesKey, 'data' => '']; } $pc = new Prpcrypt($this->m_encodingAesKey); if ($timeStamp == null) { $timeStamp = time(); } $sha1 = new SHA1; $array = $sha1->getSHA1($this->m_token, $timeStamp, $nonce, $encrypt); $ret = $array[0]; if ($ret != 0) { //return $ret; return ['ErrorCode'=>$ret, 'data' => '']; } $verifySignature = $array[1]; if ($verifySignature != $signature) { //return ErrorCode::$ValidateSignatureError; return ['ErrorCode'=>ErrorCode::$ValidateSignatureError, 'data' => '']; } $result = $pc->decrypt($encrypt, $this->m_suiteKey); if ($result[0] != 0) { //return $result[0]; return ['ErrorCode'=>$result[0], 'data' => '']; } $decryptMsg = $result[1]; //return ErrorCode::$OK; return ['ErrorCode'=>ErrorCode::$OK, 'data' => $decryptMsg]; } } ``` #### 【注册回调 示例代码】 ```php public function regcallback() { $post_data = json_encode(array( 'call_back_tag' => ["bpms_task_change", "bpms_instance_change"], 'token' => '123456', 'aes_key' => '6g5j67qlyl3zvetqxz9jiocdr586fn2zvjp78zls3il', 'url' => 'https://www.fity.cn/dingtalk/eventnotice/index', )); $rs = $this->curl_post_json($this->apihost."/call_back/register_call_back?access_token=".$this->token, $post_data); var_dump($rs);die; } ``` #### 【测试回调URL 示例代码】 ```php public function index(){ define("SUITE_KEY", "dingxxxxxxxxxxxxxxxx"); define("TOKEN", "123456"); define("ENCODING_AES_KEY", "6g5j67qlyl3zvetqxz9jiocdr586fn2zvjp78zls3il"); $signature = $_GET["signature"]; $timeStamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $postdata = file_get_contents("php://input"); $postList = json_decode($postdata,true); $encrypt = $postList['encrypt']; $crypt = new DingtalkCrypt(TOKEN, ENCODING_AES_KEY, SUITE_KEY); $msg = ""; $res = $crypt->DecryptMsg($signature, $timeStamp, $nonce, $encrypt, $msg); if ($res['ErrorCode'] != 0){//当解密失败记录 Log::e("ErrorCode:" . $res['ErrorCode']); Log::e(json_encode($_GET)); Log::e(json_encode($encrypt)); Log::e('------------------------------------------------------------------------------------------'); }else{ Log::e("SuccessCode:" . $res['ErrorCode']); if(!$res['data']){//当返回值为空记录加密字符串信息 Log::e(json_encode($_GET)); Log::e(json_encode($encrypt)); } Log::e(json_encode($res['data'])); Log::e('------------------------------------------------------------------------------------------'); //创建成功后的回调推送 $eventMsg = json_decode($res['data']); $eventType = $eventMsg->EventType; //工作流变动:审批任务开始,结束,转交 if("bpms_task_change" === $eventType){ } //工作流变动:审批实例开始,结束 if("bpms_instance_change" === $eventType){ } //注册回调接口 回调URL返回值调试 $res = "success"; $encryptMsg = ""; $encryData = $crypt->EncryptMsg($res, $timeStamp, $nonce, $encryptMsg); if($encryData['ErrorCode'] != 0){ Log::e("ERR:" . $encryData); }else{ echo $encryData['data']; } } } ``` **【以上问题主要出现在如下API使用过程】** 1、钉钉业务事件回调 - 回调管理API说明 https://ding-doc.dingtalk.com/doc#/serverapi2/pwz3r5 2、回调事件消息体加密 https://ding-doc.dingtalk.com/doc#/faquestions/ltr370 本文最后更新于 2020-07-09 18:10:12 并被添加「钉钉 钉钉开放平台 第三方API」标签,已有 9949 位童鞋阅读过。 本文作者:未来往事 本文链接:https://felixway.cn/post/676.html 本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处
此处评论已关闭