企业微信获取第三方应用凭证

上一篇介绍了如何配置通用开发参数及通过url回调验证,

本篇将通过服务商后台配置关联小程序应用配置和获取第三方凭证及如何配置企业可信IP。

当然上篇配置的回调设置也不会白费,在下方的指令和数据回调会用到。

第三方应用开发流程

官方企业微信第三方应用开发的基本流程如下:

小程序应用设置

获取suite_ticket需要使用SuiteID参数,因为项目使用的是三方应用方式开发,

这里可以通过设置小程序->关联小程序详情。

前面的配置基础信息与应用权限不在介绍,比较简单。

配置内容描述

应用主页:必填,用户从企业微信工作台进入应用时将直接跳转到对应主页URL

桌面端独立主页:用户从企业微信桌面端工作台进入应用时跳转的应用页面URL

可信域名:仅支持可信域名内的应用调用OAuth2授权、JSSDK等

安装完成回调域名:用户安装成功后可指定跳转至该域名的链接

业务设置URL:授权企业的管理员可从企业微信后台的应用详情页免登录直接跳转该链接进行应用配置。

数据回调URL:必填,用于正确响应企业微信验证URL的请求,用于接收托管企业微信应用的用户信息、进入应用事件、通讯录变更事件。

指令回调URL:必填,用户正确响应企业微信验证URL的请求,用于接收应用(添加、删除、修改)以及ticket参数等API请求。

Secret是可以生成和改变的,SuiteID是系统生成的。

配置可信域名

配置可信域名:先填写网站域名,不要写http或者https前缀,直接是网站域名。

如下:

具体怎么验证可信域名呢,接着点击检验可信域名归属:

需要把这个文件下载后,上传到网站域名下,并且可以访问到;

放好之后,如果验证不成功,可能有缓存,等待几分钟在尝试。

设置回调配置

这几项就关于回调的参数, 之前配置过url/token/encodingAESKey直接再粘贴过来即可。

指令回调和数据回调地址可以写上篇完成的回调地址,只是要注意现在的token和EncodingAESKey换成之前调好的token和EncodingAESKey和字符串就行或者也可以把代码中的这两项换成现在新生成的。

这些可以分步配置,最后保存完成后,效果如下图:

如果暂时不知道设置项是什么作用,可以先配置一个,之后用上了再改即可。

获取ticket

设置好应用参数后,把suiteID、secret粘贴一下,在代码中要使用。

控制器接收参数

这里因为一开始不确定参数情况,所以对接收的所有参数存储到日志中。

首先判断请求方式为post,然后具体进入接收数据环节。

经过多次调试后确定需要接收四个参数内容,其中msg_signature/timestamp/nonce三个可直接通过字段名获取到,比较麻烦的是密文数据,需要使用php://input获取。

内容是一个xml格式的字符串。

内容如下:

public function wxNotify()
{$obj = new CompanyWxPushService();$all = request()->all();writeRecordLog('companyWechat.log', request()->method());writeRecordLog('companyWechat.log', var_export($all, true));if (request()->isMethod('POST')) {$msg_signature = request()->input('msg_signature');$timeStamp = request()->input('timestamp');$nonce = request()->input('nonce');// post请求的密文数据$sReqData = file_get_contents('php://input');echo $obj->callbackPOST($msg_signature, $timeStamp, $nonce, $sReqData);}  die();
}

业务层解析

下面的处理中思路是:收到post请求之后

1.解析出url上的参数,包括消息体签名(msg_signature),时间戳(timestamp)以及随机数字串(nonce);

2.验证消息体签名的正确性。

3.将post请求的数据进行xml解析,并将<Encrypt>标签的内容进行解密,

解密出来的明文是xml格式的字符串需要转变为xml对象。

4.判断对象的infotype获取suite_ticket并进行存储,之后调用access_token需要使用。

内容如下:

class CompanyWxPushService
{//  接收信息时的加解密参数protected static $encodingAesKey = "随机生成的encodingAESKey";// 接收信息时的校验Tokenprotected static $token = "随机生成的token";protected static $corpId = "服务商注册后获取的corpID";protected static $SuiteID = '小程序应用详情获取的suiteID';protected static $Secret = '小程序应用详情获取的secret';/*** 企业微信post回调解析* @param $sReqMsgSig* @param $sReqTimeStamp* @param $sReqNonce* @param $sReqData* @return string*/public function callbackPOST($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData){$sMsg = "";  // 解析之后的明文$wxcpt = new \WXBizMsgCrypt(self::$token, self::$encodingAesKey, self::$SuiteID);$errCode = $wxcpt->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData, $sMsg);writeRecordLog('companyWechat.log', $errCode);if ($errCode == 0) {// 解密成功,sMsg即为xml格式的明文writeRecordLog('companyWechat.log', "解密成功:\r\n". var_export($sMsg, true));// TODO: 对明文的处理// 解析该xml字符串,利用simpleXMLlibxml_disable_entity_loader(true);//禁止xml实体解析,防止xml注入$xml = simplexml_load_string($sMsg, 'SimpleXMLElement', LIBXML_NOCDATA);switch ($xml->InfoType) {case 'suite_ticket': // 存储suite_ticket$log_desc = '存储suite_ticket:' . $xml->SuiteTicket;self::$redisWechat->setCompanyTicket($xml->SuiteTicket);break;default:$log_desc = '未知的类型:' . $xml->InfoType;break;}writeRecordLog('companyWechat.log', '解析日志:' . $log_desc);return 'success';} else {return "ERR: " . $errCode . "\n\n";}}
}

获取ticket

企业微信服务器会定时(每十分钟)向指令回调 URL 推送 suite_ticket,在指令回调的后台逻辑中解密消息体即可得到对应的 InfoType 和 SuiteTicket 。

不同类型的指令回调会通过不同的 InfoType 进行区分,在每次解密得到 suite_ticket 后,应在服务端临时缓存起来。

也可通过刷新ticket按钮来多次快速获取验证解析。

日志情况如下:

获取 suite_access_token

获取suite_access_token即为获取第三方凭证,这个在整个开发中很重要,接下来的几个接口都需要三方凭证;在成功接受并且缓存 suite_ticket 之后,我们可以主动来获取 suite_access_token。获取suite_access_token时,需要 suite_id,suite_secret suite_ticket 作为参数。

请求方式

POST

请求地址

https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token

参数说明

参数

是否必须

说明

suite_id

第三方应用id或者代开发应用模板id。第三方应用以ww或wx开头应用id(对应于旧的以tj开头的套件id);代开发应用以dk开头

suite_secret

第三方应用secret 或者代开发应用模板secret

suite_ticket

企业微信后台推送的ticket,即回调中获取的ticket

控制器

暂时先写一个请求,看一下返回内容。

/*** 获取企业微信 suite_access_token*/
public function companyAccessToken()
{$obj = new CompanyWxPushService();print_r($obj->companyAccessToken());die;
}

业务层处理

需要三方应用SuiteID和Secret参数和之前回调返回中解密后获取的suite_ticket。

Suite_ticket这一步是通过回调获取的suite_ticket内容,设置的redis缓存。

/*** 获取企业微信 suite_access_token* @return bool|string*/
public function companyAccessToken()
{$url = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";$params = ['suite_id' => self::$SuiteID,'suite_secret' => self::$Secret,'suite_ticket' => self::$redisWechat->getCompanyTicket()];return $this->linkCurl($url, 'POST', $params);
}/*** 请求接口返回内容* @param $url : 请求的URL地址* @param $method : 请求方式POST|GET* @param bool $params : 请求的参数* @return bool|string*/
protected function linkCurl($url, $method, $params = false)
{$ch = curl_init();curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_FAILONERROR, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);if (strpos("$" . $url, "https://") == 1) {curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);}curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);curl_setopt($ch, CURLOPT_TIMEOUT, 60);if ($method == "POST") {curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, json($params));} else if ($params) {curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));}$response = curl_exec($ch);if ($response === FALSE) return false;curl_close($ch);return $response;
}

响应:

{"errcode":60020,"errmsg":"not allow to access from your ip:client ip 123......."}

怀疑是没注册应用和配置企业可信ip。

响应60020是未设置IP白名单,可查看下方第三方应用企业可信IP设置。

设置后,再次请求返回正常。

{"suite_access_token":"tpBubbmIlo_N5zoCKXvz_9q6IanamtrZMB2rBI_Mnh48m9Fqwr7dwak3QZZPJA5O7KBQ_736ks3yogBT5djZerXrajnDUk9hsvP2xGVMnJSq1jPKDvlzIbayUoIX3lCr","expires_in":7200}

 

响应参数描述

参数

是否必须

说明

suite_id

第三方应用id或者代开发应用模板id。第三方应用以ww或wx开头应用id(对应于旧的以tj开头的套件id);代开发应用以dk开头

suite_secret

第三方应用secret 或者代开发应用模板secret

suite_ticket

企业微信后台推送的ticket

 

企业可信IP设置

第三方应用或待开发应用需要在服务商后台->服务商信息->基本信息

中设置ip白名单;1分钟后生效。

设置白名单

注意:一般员工账号看不到,需要切换管理员账号。

总结

通过第三方应用开发流程可以知道获取第三方凭证suite_access_token的原因,在之后的API中是一个很重要的参数;在获取的途中,因为不熟悉遇到设置白名单的问题,权限是普通权限看不到服务商功能,之后才发现是权限问题,希望其他开发者不会有这个困惑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/145810.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Beego之Bee工具使用

1、bee工具使用 bee 工具是一个为了协助快速开发 Beego 项目而创建的项目&#xff0c;通过 bee 你可以很容易的进行 Beego 项目的创 建、热编译、开发、测试、和部署。Bee工具可以使用的命令&#xff1a; [rootzsx ~]# bee 2023/02/18 18:17:26.196 [D] init global config…

van-dialog弹窗异步关闭-校验表单

van-dialog弹窗异步关闭 有时候我们需要通过弹窗去处理表单数据&#xff0c;在原生微信小程序配合vant组件中有多种方式实现&#xff0c;其中UI美观度最高的就是通过van-dialog嵌套表单实现。 通常表单涉及到是否必填&#xff0c;在van-dialog的确认事件中直接return是无法阻止…

软件测试面试-如何定位线上出现bug

其实无论是线上还是在测试出现bug&#xff0c;我们核心的还是要定位出bug出现的原因。 定位出bug的步骤&#xff1a; 1&#xff0c;如果是必现的bug&#xff0c;尽可能的复现出问题&#xff0c;找出引发问题的操作步骤。很多时候&#xff0c;一个bug的产生&#xff0c;很多时…

Java基础笔记

1.数据类型在java语言中包括两种: 第一种:基本数据类型 基本数据类型又可以划分为4大类8小种: 第一类:整数型 byte , short,int, long(没有小数的&#xff09; 第二类:浮点型 float,aouble(带有小数的&#xff09; 第三类:布尔型 boole…

计算机毕业设计 基于Vue的米家商城系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

React经典初级错误

文章 前言错误场景问题分析解决方案后言 前言 ✨✨ 他们是天生勇敢的开发者&#xff0c;我们创造bug&#xff0c;传播bug&#xff0c;毫不留情地消灭bug&#xff0c;在这个过程中我们创造了很多bug以供娱乐。 前端bug这里是博主总结的一些前端的bug以及解决方案&#xff0c;感兴…

FastAdmin表格顶部增加toolbar按钮

效果入下图&#xff0c;在表格顶部增加一个自定义按钮&#xff0c;点击确认后请求服务器接口 表格对应的index.html中 <div class"panel-body"><div id"myTabContent" class"tab-content"><div class"tab-pane fade active …

【开源】基于JAVA的服装店库存管理系统

项目编号&#xff1a; S 052 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S052&#xff0c;文末获取源码。} 项目编号&#xff1a;S052&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 服…

Go 语言变量类型和声明详解

在Go中&#xff0c;有不同的变量类型&#xff0c;例如&#xff1a; int 存储整数&#xff08;整数&#xff09;&#xff0c;例如123或-123float32 存储浮点数字&#xff0c;带小数&#xff0c;例如19.99或-19.99string - 存储文本&#xff0c;例如“ Hello World”。字符串值用…

微服务学习 | Ribbon负载均衡、Nacos注册中心、微服务技术对比

Ribbon负载均衡 负载均衡流程 负载均衡策略 通过定义IRule实现可以修改负载均衡规则&#xff0c;有两种方式&#xff1a; 1. 代码方式:在服务消费者order-service中的OrderApplication类中&#xff0c;定义一个新的IRule: 2.配置文件方式: 在order-service的application.yml…

【C++学习手札】模拟实现vector

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;くちなしの言葉—みゆな 0:37━━━━━━️&#x1f49f;──────── 5:28 &#x1f504; ◀️ ⏸ ▶️ ☰…

Verilog基础:三段式状态机与输出寄存

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html 对于Verilog HDL而言&#xff0c;有限状态机(FSM)是一种重要而强大的模块&#xff0c;常见的有限状态机书写方式可以分为一段式&#xff0c;二段式和三段式&#xff0c;笔者强烈建议使用三…

进程信号(linux)

什么是信号 信号是一种用于进程之间通信或操作的一种手段&#xff0c;通常一个进程会在任意时刻接收到系统发送的信号&#xff0c;因此信号也可以看做是一种进程事件异步通知的手段。 一个进程可以对信号有三种操作&#xff1a; 默认操作&#xff1a;默认进行信号对应的操作…

【Python】【应用】Python应用之一行命令搭建HTTP、FTP服务器

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;Python应用&…

python爬虫 之 JavaScript 简单基础

文章目录 在网页使用JavaScript 代码的方式常用的JavaScript 事件常用的JavaScript 对象 在网页使用JavaScript 代码的方式 在网页中使用 JavaScript 代码的方式主要有三种&#xff1a; 内联方式&#xff08;Inline&#xff09;&#xff1a; 在 HTML 文件中直接嵌入 JavaScrip…

简单的 UDP 网络程序

文章目录&#xff1a; 简单的UDP网络程序服务端创建套接字服务端绑定启动服务器udp客户端本地测试INADDR_ANY 地址转换函数关于 inet_ntoa 简单的UDP网络程序 服务端创建套接字 我们将服务端封装为一个类&#xff0c;当定义一个服务器对象之后&#xff0c;需要立即进行初始化…

【uniapp/uview1.x】u-upload 在 v-for 中的使用时, before-upload 如何传参

引入&#xff1a; 是这样一种情况&#xff0c;在接口获取数据之后&#xff0c;是一个数组列表&#xff0c;循环展示后&#xff0c;需要在每条数据中都要有图片上传&#xff0c;互不干扰。 分析&#xff1a; uview 官网中有说明&#xff0c;before-upload 是不加括号的&#xff…

《QT从基础到进阶·三十三》QT插件开发QtPlugin

插件和dll区别&#xff1a; 插件 插件主要面向接口编程&#xff0c;无需访问.lib文件&#xff0c;热插拔、利于团队开发。即使在程序运行时.dll不存在&#xff0c;也可以正常启动&#xff0c;只是相应插件功能无法正常使用而已&#xff1b; 调用插件中的方法只要dll即可&#x…

Ajax 之XMLHttpRequest讲解

一直以来都听别人说Ajax,今天终于接触到了。。。。。。。。。。 一.什么是Ajax? 答: AJAX即“Asynchronous Javascript And XML”&#xff08;异步JavaScript和XML&#xff09;&#xff0c;是指一种创建交互式网页应用的网页开发技术。 AJAX 异步 JavaScript和XML&#x…

Linux(2):初探

Linux 是什么 Linux 就是一套操作系统。Linux 就是核心与系统呼叫接口那两层。 应用程序不算 Linux。 Linux 提供了一个完整的操作系统当中最底层的硬件控制与资源管理的完整架构&#xff0c; 这个架构是沿袭Unix 良好的传统来的&#xff0c;相当的稳定而功能强大。 在 Lin…