PHP:连接钉钉接口-钉钉回调事件,本地测试数据
前置数据参考

数据说明:参见官方文档回调事件消息体加解密 - 钉钉开放平台 (dingtalk.com)
URL后面带的参数:
signature=5a65ceeef9aab2d149439f82dc191dd6c5cbe2c0×tamp=1445827045067&nonce=nEXhMP4r
Post参数:
{ "encrypt":"1a3NBxmCFwkCJvfoQ7WhJHB+iX3qHPsc9JbaDznE1i03peOk1LaOQoRz3+nlyGNhwmwJ3vDMG+OzrHMeiZI7gTRWVdUBmfxjZ8Ej23JVYa9VrYeJ5as7XM/ZpulX8NEQis44w53h1qAgnC3PRzM7Zc/D6Ibr0rgUathB6zRHP8PYrfgnNOS9PhSBdHlegK+AGGanfwjXuQ9+0pZcy0w9lQ==" }
Env.TOKEN:123456
Env.ENCODING_AES_KEY:4g5j64qlyl3zvetqxz5jiocdr586fn2zvjpa8zls3ij
Env.KEY:suite4xxxxxxxxxxxxxxx
代码(info_return.php)
<?php
define( 'TOKEN', '123456' );
define( 'ENCODING_AES_KEY', '4g5j64qlyl3zvetqxz5jiocdr586fn2zvjpa8zls3ij' );
define( 'SUITE_KEY', 'suite4xxxxxxxxxxxxxxx' );
// 包含 DingtalkCrypt 类
require_once 'DingtalkCrypt.php';$signature = $_GET[ 'signature' ];
$timeStamp = $_GET[ 'timestamp' ];
$nonce = $_GET[ 'nonce' ];
// $postdata = file_get_contents( 'php://input' );
// $postList = json_decode( $postdata, true );
// $encrypt = $postList[ 'encrypt' ];
$encrypt = '1a3NBxmCFwkCJvfoQ7WhJHB+iX3qHPsc9JbaDznE1i03peOk1LaOQoRz3+nlyGNhwmwJ3vDMG+OzrHMeiZI7gTRWVdUBmfxjZ8Ej23JVYa9VrYeJ5as7XM/ZpulX8NEQis44w53h1qAgnC3PRzM7Zc/D6Ibr0rgUathB6zRHP8PYrfgnNOS9PhSBdHlegK+AGGanfwjXuQ9+0pZcy0w9lQ==';
$crypt = new DingtalkCrypt( TOKEN, ENCODING_AES_KEY, SUITE_KEY );$msg = '';
$errCode = $crypt->DecryptMsg( $signature, $timeStamp, $nonce, $encrypt, $msg );if ( $errCode != 0 ) {echo ( json_encode( $_GET ) . ' ERR:' . $errCode );/*** 创建套件时检测回调地址有效性,使用CREATE_SUITE_KEY作为SuiteKey*/// $crypt = new DingtalkCrypt( TOKEN, ENCODING_AES_KEY, CREATE_SUITE_KEY );// $errCode = $crypt->DecryptMsg( $signature, $timeStamp, $nonce, $encrypt, $msg );if ( $errCode == 0 ) {// echo( 'DECRYPT CREATE SUITE MSG SUCCESS ' . json_encode( $_GET ) . ' ' . $msg );$eventMsg = json_decode( $msg );$eventType = $eventMsg->EventType;if ( 'check_create_suite_url' === $eventType ) {$random = $eventMsg->Random;$testSuiteKey = $eventMsg->TestSuiteKey;$encryptMsg = '';$errCode = $crypt->EncryptMsg( $random, $timeStamp, $nonce, $encryptMsg );if ( $errCode == 0 ) {echo ( 'CREATE SUITE URL RESPONSE: ' . $encryptMsg );echo $encryptMsg;} else {echo ( 'CREATE SUITE URL RESPONSE ERR: ' . $errCode );}} else {// should never happened}} else {echo ( json_encode( $_GET ) . 'CREATE SUITE ERR:' . $errCode );}return;
} else {/*** 套件创建成功后的回调推送*/// echo( 'DECRYPT MSG SUCCESS ' . json_encode( $_GET ) . ' ' . $msg );$eventMsg = json_decode( $msg );$eventType = $eventMsg->EventType;/*** 套件ticket*/if ( 'suite_ticket' === $eventType ) {Cache::setSuiteTicket( $eventMsg->SuiteTicket );}/*** 临时授权码*/else if ( 'tmp_auth_code' === $eventType ) {$tmpAuthCode = $eventMsg->AuthCode;Activate::autoActivateSuite( $tmpAuthCode );}/*** 授权变更事件*//*user_add_org : 通讯录用户增加user_modify_org : 通讯录用户更改user_leave_org : 通讯录用户离职org_admin_add :通讯录用户被设为管理员org_admin_remove :通讯录用户被取消设置管理员org_dept_create : 通讯录企业部门创建org_dept_modify : 通讯录企业部门修改org_dept_remove : 通讯录企业部门删除org_remove : 企业被解散*/ else if ( 'user_add_org' === $eventType ) {echo ( json_encode( $_GET ) . ' ERR:user_add_org' );// handle auth change event} else if ( 'user_modify_org' === $eventType ) {echo ( json_encode( $_GET ) . ' ERR:user_modify_org' );// handle auth change event} else if ( 'user_leave_org' === $eventType ) {echo ( json_encode( $_GET ) . ' ERR:user_leave_org' );// handle auth change event}/*** 应用被解除授权的时候,需要删除相应企业的存储信息*/else if ( 'suite_relieve' === $eventType ) {$corpid = $eventMsg->AuthCorpId;ISVService::removeCorpInfo( $corpid );// handle auth change event} else if ( 'change_auth' === $eventType ) {// handle auth change event}/*** 回调地址更新*/else if ( 'check_update_suite_url' === $eventType ) {$random = $eventMsg->Random;$testSuiteKey = $eventMsg->TestSuiteKey;$encryptMsg = '';$errCode = $crypt->EncryptMsg( $random, $timeStamp, $nonce, $encryptMsg );if ( $errCode == 0 ) {// echo( 'UPDATE SUITE URL RESPONSE: ' . $encryptMsg );echo $encryptMsg;return;} else {// echo( 'UPDATE SUITE URL RESPONSE ERR: ' . $errCode );}} else {// should never happen}$res = 'success';$encryptMsg = '';$errCode = $crypt->EncryptMsg( $res, $timeStamp, $nonce, $encryptMsg );if ( $errCode == 0 ) {echo $encryptMsg;// echo( 'RESPONSE: ' . $encryptMsg );} else {// echo( 'RESPONSE ERR: ' . $errCode );}
}
相关文章:
PHP:连接钉钉接口-钉钉回调事件,本地测试数据
前置数据参考 数据说明:参见官方文档回调事件消息体加解密 - 钉钉开放平台 (dingtalk.com) URL后面带的参数: signature5a65ceeef9aab2d149439f82dc191dd6c5cbe2c0×tamp1445827045067&noncenEXhMP4r Post参数: { &quo…...
【C++标准模版库】vector的介绍及使用
vector 一.vector的介绍二.vector的使用1.vector 构造函数2.vector 空间增长3.vector 增删查改4.vector 迭代器的使用1.正向迭代器2.反向迭代器 5.victor 迭代器失效问题(重点) 三.vector不支持 流提取与流插入四.vector存储自定义类型1.存储string2.存储…...
数说故事|引爆社媒的森贝儿IP,品牌如何实现流量变现?
以可爱、雅痞、贱萌......的外表加魔性舞姿出圈的可爱小狗——森贝儿贵宾犬Milo,用“可爱微怒”的表情演绎着当代打工人的“疯态”,并迅速晋升成不少打工人高频使用的表情包。 最近几年,“萌系”爆款IP频出,用小动物的形象、可爱…...
使用openpyxl库对Excel条件格式的深度探索
哈喽,大家好,我是木头左! openpyxl中的条件格式 在openpyxl中,可以使用ConditionalFormatting类来创建和管理条件格式。这个类有两个主要的方法:add_conditional_formatting()和remove_conditional_formatting(),分别用于添加和删除条件格式。 add_conditional_formatt…...
原生javascript中的ajax通信技术
AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。也就是实现前后端交互的功能。以下是使用AJAX的基本步骤和代码演示: 1.创建一个XMLHttpRequest对象: var xhr…...
SpringBoot Vue用自签名证书SSL配置https,http转发到https(整理文章)
要配置https地址访问,需要向服务器商申请和使用SSL证书。由于是测试阶段,我们自己创建SSL证书,叫作自签名证书。 1.创建自签名证书 Vue前端生成自签名证书我们用openssl 参考文章一 参考文章二SpringBoot后端生成自签名证书用JDK自带的keyt…...
嵌入式人工智能(41-基于树莓派4B的串口蓝牙模块AT09-cc2541)
1、串口蓝牙模块AT-09 AT-09是一种串口蓝牙模块,可实现串口与蓝牙之间的数据传输。AT-09模块基于蓝牙4.0技术,具有低功耗、高传输速率和广泛的应用范围。 AT-09模块支持AT指令,通过串口与外部设备进行通信。用户可以使用AT指令对模块进行配…...
C++ 动态规划
子序列子串相关 单个指一个数组或字符串,两个指两个数组或字符串。 最长上升子序列-单个 dp[i]:以下标i为结尾的递增的最长子序列长度。 位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 1 的最大值。 class Solution { public:int l…...
回溯问题总结
一、子集问题 模板问题 给定一个序列[1,n],求这个序列的所有子集 输入描述: 一个正整数n(1 < n < 12) 输出描述: 每个子集一行,输出所有子集。 输出顺序为: (1)元素个数少的子集优先输出;…...
GraphRAG如何使用ollama提供的llm model 和Embedding model服务构建本地知识库
使用GraphRAG踩坑无数 在GraphRAG的使用过程中将需要踩的坑都踩了一遍(不得不吐槽下,官方代码有很多遗留问题,他们自己也承认工作重心在算法的优化而不是各种模型和框架的兼容性适配性上),经过了大量的查阅各种资料以…...
.net # 检查 带有pdf xss
1.解决pdf含javasprct脚本动作,这里是验证pdf内部事件。相关pdf文件下载: 测试pdf文件 相关包 iTextSharp 5.5.13.4 iTextSharp using iTextSharp.text.pdf; using iTextSharp.text.pdf.parser;private Boolean IsPdfSafe(Stream stream){// PdfReader…...
【React】探讨className的正确使用方式
文章目录 一、className的正确用法二、常见错误解析三、实例解析四、错误分析与解决五、注意事项六、总结 在React开发中,正确使用className属性对组件进行样式设置至关重要。然而,由于JavaScript和JSX的特殊性,开发者常常会犯一些小错误&…...
打靶记录5——靶机hard_socnet2
靶机: https://download.vulnhub.com/boredhackerblog/hard_socnet2.ova目标: 取得root权限 涉及攻击方法 主机发现端口扫描SQL注入文件上传蚁剑上线XMLRPC命令执行逆向工程动态调试漏洞利用代码编写 方法 CVE-2021-3493缓冲器溢出漏洞 学习目标 …...
独立站+TikTok达人:自主营销与创意内容的完美结合
在全球电商市场迅猛发展的今天,独立站和TikTok达人的结合正在创造一种全新的电商营销模式。独立站作为电商平台,其自主性和灵活性为商家提供了广阔的发展空间;而TikTok达人凭借其独特的内容创作能力和庞大的粉丝基础,成为推动销售…...
【启明智显分享】适用于多功能养生壶、茶吧机的2.8寸触摸彩屏解决方案
健康生活理念不断深入人心,多功能养生壶、茶吧机等智能产品成为现代家庭的热门小家电。为推动智能家居个性化、多样化发展,启明智显推出了基于SC05 Plus 2.8寸触摸彩屏的多功能养生壶、茶吧机的解决方案,旨在提升养生壶与茶吧机的用户体验与操…...
WAF绕过技术(PKAV团队)
目录 主流WAF的绕过技术 Web容器的特性 1. IIS+ASP的神奇% 2. IIS的Unicode编码字符 3. HPP(HTTP Parameter Pollution): HTTP参数污染 4. 畸形HTTP请求 Web应用层的问题 1. 多重编码问题 2. 多数据来源的问题 WAF自身的问题 1. 白名单机制 2. 数据获取方式存在缺陷…...
『 Linux 』POSIX 信号量与基于环形队列的生产者消费者模型
文章目录 信号量概念POSIX 信号量基于环形队列的生产者消费者模型基于环形队列的生产者消费者模型编码实现基于环形队列的生产者消费者模型发送任务测试 信号量概念 信号量是一种用于多线程或多进程间同步的机制; 其定义是一个整形变量,本质上信号量可以看成是一个计数器,用来描…...
python中的字符串方法
python中的字符串 举个例子先 name = 貂蝉开大 #声明了一个字符串 print(name) # 打印了一个字符串 print(name[0:1] #输出貂蝉 print(name[2:3] #输出开大 扩展方法 find() # 查找字符串中某个字符的索引 index_ = name.find("貂") print(index_) # 输出 …...
python实现consul的服务注册与注销
我在使用consul的时候主要用于prometheus的consul服务发现,把数据库、虚拟机信息发布到consul,prometheus通过consul拿到数据库、虚拟机信息去采集指标信息。 此篇文章前提是已经安装好consul服务以后,安装consul请参考二进制方式部署consul…...
校园选课助手【2】-重要的登录模块
用户登录模块技术要点: 密码通过MD5加密传输分布式session存储用户登录信息自定义注解进行字段校验自定义拦截器完成登录验证 下面依次给出代码和详细解释: 1.使用 MD5 二次加密用户登录信息,前端先通过密码加上盐进行MD5加密交给服务器&a…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
