公司业务需要开发企业微信,注册三方服务商审核通过后,
开始配置开发信息。本篇中记录在调试url验证中遇到错误及解决方式。
目录
准备工作
下载php加解密库
下载文件说明
设置白名单
设置路径
参数说明
设置ip
回调处理
回调类型:
1、Get 类型
2、Post 类型
Get 回调实现
设置路由
控制器
业务层处理
配置开发信息
遇到问题
发现问题
解决方案
在回调的实现逻辑中需要进行加解密计算,企业微信已经提供了 C++ Python PHP Java Go C# Node.js 等语言版本的加解密库,并且均提供了解密、加密、验证URL三个接口,开发者可以根据开发需要 下载加解密库。
下载文件
WXBizMsgCrypt.php文件提供了WXBizMsgCrypt类的实现,是用户接入企业微信的接口类。Sample.php提供了示例以供开发者参考。errorCode.php, pkcs7Encoder.php, sha1.php, xmlparse.php文件是实现这个类的辅助类,开发者无须关心其具体实现。
WXBizMsgCrypt类封装了VerifyURL, DecryptMsg, EncryptMsg三个接口,分别用于开发者验证接收消息。的url、接收消息的解密以及开发者回复消息的加密过程。使用方法可以参考Sample.php文件。
在开发者中心->工具->开发配置->IP白名单->点击编辑按钮,
添加白名单IP列表
参数内容 |
说明 |
白名单IP列表 |
服务商调用企业微信API时的合法IP列表,只有白名单内的IP才能正常调用企业微信API,修改后立即生效。支持“222.209.201.*” 这样用通配符表示IP段;多个IP以英文分号;分隔 |
我设置的是自己本机ip,并把最后一位设置为*,防止ip变动。
加解密库加到项目中,最好外网可以访问到,否则估计要实现内网穿透。
第三方应用的回调配置有数据回调和指令回调两种。
数据回调,用于接收托管企业微信应用的用户消息、进入应用事件、通讯录变更事件。
指令回调,用于接收应用授权变更事件(应用添加、删除、修改)以及ticket参数,ticket说明详API接口说明。
对于数据回调和指令回调的两个 URL ,在服务端的实现时,都必须同时支持 HttpGet 以及 HttpPost两种能力。
仅用于在应用创建配置应用信息时的验证,企业微信服务端会向回调URL发起一个 Get 请求,当该回调URL按照约定进行了响应后,表明第三方服务具备解析企业微信推送消息的能力。
用于实际的业务请求,比如应用菜单的点击事件,用户消息等。当有回调的行为发生时,企业微信服务端会向该回调URL发起一个 Post 请求,同时数据会已加密的形式推送到该回调 URL,第三方服务商接受信息、解密信息,处理业务逻辑,并且按照约定进行响应即可。
目前只介绍get回调实现。
在laravel中实现设置路由。
Route::any('wxNotify', 'Api\ApiOtherController@companyWxNotify');
接收参数,并返回响应。
public function wxNotify()
{
$obj = new CompanyWxPushService();
$all = request()->all();
writeRecordLog('companyWechat.log', var_export($all, true));
if (request()->isMethod('GET')) {
// 获取参数
$msg_signature = request()->input('msg_signature');
$timeStamp = request()->input('timestamp');
$nonce = request()->input('nonce');
$echoStr = request()->input('echostr');
echo $obj->callbackGET($msg_signature, $timeStamp, $nonce, $echoStr);
}
die();
}
接收到该请求时:
1.解析出Get请求的参数,包括消息体签名(msg_signature),时间戳(timestamp),随机数字串(nonce)以及公众平台推送过来的随机加密字符串(echostr),这一步注意作URL解码;
2.验证消息体签名的正确性;
3. 解密出echostr原文,将原文当作Get请求的response,返回给公众平台
第2,3步可以用公众平台提供的库函数VerifyURL来实现。
内容如下:
class CompanyWxPushService
{
// 接收信息时的加解密参数
protected static $encodingAesKey = "随机生成的encodingAESKey";
// 接收信息时的校验Token
protected static $token = "随机生成的token";
protected static $corpId = "服务商注册后获取的corpID";
/**
* 企业微信GET回调处理(URL地址校验)
* @param $sVerifyMsgSig
* @param $sVerifyTimeStamp
* @param $sVerifyNonce
* @param $sVerifyEchoStr
* @return string
*/
public function callbackGET($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr)
{
$sVerifyEchoStr = str_replace(" ", "+", $sVerifyEchoStr);
$wxcpt = new \WXBizMsgCrypt(self::$token, self::$encodingAesKey, self::$corpId);
// 调用验证函数
$sEchoStr = "";
$errCode = $wxcpt->VerifyURL($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr, $sEchoStr);
if ($errCode == 0) {
return $sEchoStr;
} else {
return "ERR: " . $errCode;
}
}
}
开发者完成注册之后,即可登录进入服务商管理后台。
在后台主页->应用管理->通用开发参数栏->点击编辑按钮,配置基本开发信息。
填入url回调地址,随机生成token/encodingAESKey;
点击保存或者确定,就会发送回调消息进行验证,成功即可保存。
一直返回-40001全局错误码,
对照全局错误码提示是:
40001 |
不合法的secret参数 |
比对了好几遍token/encodingAESKey/corpId
又重新生成了token和encodingAESKey还是不行。
中间又去网上也没找到类似的问题。
最后把回调的数据在本地,把接收数据改为固定的回调信息,发现就正常解析出来了。
最后一个一个参数经过比对,发现接收数据时会把加密字符串中的+解析成空格。
如下:
对加密字符串执行替换处理,把空格换成+。
内容如下:
$sVerifyEchoStr = str_replace(" ", "+", $sVerifyEchoStr);
本地修改后,验证了好几次都能正确解析出加密字符串内容。
之后提交保存后,验证通过了。