编辑者模式原理图:
开发者模式原理图:
输入网址 http://mp.weixin.qq.com 进入微信公众号平台注册账号,再点击 “基本配置” 进行自定义服务器的配置(如下图),
进入基本配置之后选择 “服务器配置” 选项进行服务器配置,填写服务器访问地址上的校验脚本(需先上传到服务器/var/www
目录下),接着填写 token,可以随便填但须跟脚本里的 TOKEN 常量值一致,然后填写EncodingAESKey(这是一个加密的
密钥,可以自己设置,最好直接随机生成),最后选择 “消息加解密方式”,这个视情况而定,正式使用时推荐用 “安全模式”,
这里选 “明文模式” 即可,全部填写完毕直接单击 “提交” 按钮即可,一切正常的话会提示 “Token 验证成功” 字眼。
由于微信测试号已经提供了比自己申请的未认证的微信公众号多得多的接口测试,所以直接申请一个微信测试号进行测试即可。
如下图所示接口测试号申请及配置:
测试结果如下:
至此,已经成功在微信服务器与你自己的服务器直接搭建了桥梁,通信正常。
校验脚本如下所示,我因为是之前看了视频,里面加了这段代码(如下所示),导致我一直提交提示
"Token 验证失败",我搞了一天啊,因为不懂在哪看报错信息所以好尴尬,最后尝试把下面代码注释
后果然正常提交成功!!!我想应该是只 throw 而没 catch 异常的缘故吧。
if(!define('TOKEN')){//坑!写了这句话一直token验证报错.
throw new Exception('TOKEN is not defined!');
}
校验脚本 index.php 代码如下:
<?php
//define your token
//定义TOKEN密钥(主要为了桥接微信服务器与自定义服务器)
define("TOKEN", "yibin");
$wechatObj = new wechatCallbackapiTest();
if($_GET["echostr"]){//只需要首次验证
$wechatObj->valid();
}else{
$wechatObj->responseMsg();
}
//wechatCallbackapiTest类,主要用于微信开发验证与回复
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];//接收随机字符串
//valid signature , option
if($this->checkSignature()){
//如果验证成功,返回随机字符串,代表桥接成功。
echo $echoStr;
exit;
}
}
//定义自动回复功能
public function responseMsg()
{
//get post data, May be due to the different environments
//$GLOBALS["HTTP_RAW_POST_DATA"]与$_POST方法功能类似,主要用于接收http中的post请求,但是$GLOBALS["HTTP_RAW_POST_DATA"]可以接收xml数据。
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
//extract post data
//如果发送过来的xml数据不为空
if (!empty($postStr)){
//安全处理,解析xml时不解析外部实体,防止文件产生泄漏(xxe漏洞)
libxml_disable_entity_loader(true);
//载入xml文件到字符串
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
//发送者(手机客户端)
$fromUsername = $postObj->FromUserName;
//接收者(微信公众账号)
$toUsername = $postObj->ToUserName;
//接收到的关键词
$keyword = trim($postObj->Content);
//时间戳
$time = time();
//文本消息xml模板
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
if(!empty( $keyword ))
{
$msgType = "text";
$contentStr = "Welcome yibin94 to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
//验证数字签名
private function checkSignature()
{
//校验TOKEN密钥
/*if(!define('TOKEN')){//坑!写了这句话一直token验证报错.
throw new Exception('TOKEN is not defined!');
}*/
//接收数字签名
$signature = $_GET["signature"];
//接收时间戳
$timestamp = $_GET["timestamp"];
//接收随机数
$nonce = $_GET["nonce"];
//定义$token变量获取TOKEN密钥
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);//按字典序排序
$tmpStr = implode( $tmpArr );//转换数组为字符串
$tmpStr = sha1( $tmpStr );//通过哈希算法进行加密
//与发送过来的随机字符串进行比对,成功则返回true,否则返回false。
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
}
?>