微信公众平台开发之开发者原理
白羽 2018-06-12 来源 :网络 阅读 1643 评论 0

摘要:本文主要讲述了开发者模式的原理,注意【开发者模式】和【自动回复功能】不能共存,也就是说一个处于启用状态,另一个只能处于停用状态。其实微信公众平台的开发和网页编写时一样的,只不过显示在微信客户端中而不是浏览器网页界面。希望本文对大家学微信有所帮助。




一、开发者原理


二、启用开发者模式


三、一个简单的例子

 

一、        开发者原理

要想更好的开发微信公众平台,理解一下原理还是很重要的,如果出现了错误这样也就更容易调试。

 微信公众平台开发之开发者原理

微信平台有一个服务器A用于与手机微信客户端通讯(接收和发送消息),如果启用开发者模式,还需要一个服务器B(需要自己准备),服务器A接收客户端发来的消息a,并将消息a发送给服务器B,在服务器B中对消息进行处理返回消息b(这里便是开发者主要要实现的功能)给服务器A,微信平台的服务器A再将消息b发给客户端,这就是大体的消息发送和回应的原理。

以上描述的是在已经成为开发者之后,公众号的关注者发送消息时的情景。

 

在初次申请成为开发者时,你需要准备的是一个服务器(我使用的是SAE),然后需要在公众号中配置一下,主要也就是告诉公众号(处于服务器A中)你的服务器在哪里(服务器B的URL)以及其他信息。之后就需要一个初次验证,也就是让服务器A和服务器B相互熟悉熟悉,毕竟以后要一起工作啦。

开发模式成为开发者时的消息校验原理

在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数(signature、timestamp、nonce、echostr),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。此后,每次开发者接收用户消息的时候,微信也都会带上前面三个参数(signature、timestamp、nonce)访问开发者设置的URL。


 微信公众平台开发之开发者原理  


开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

加密/校验流程如下:

1. 将token、timestamp、nonce三个参数进行字典序排序

2. 将三个参数字符串拼接成一个字符串进行sha1加密

3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信启用接口是由代码中的checkSignature()函数来实现校验的。

有点乱的话,也没问题,之后再例子中还会再说。

 

二、        启用开发者模式

上面说的是开发者的初次验证和普通消息接收发送的原理,当然这都是在启用开发者模式之后才管用的,所以现在我们就来说一说如何启用开发者模式和相关的一些配置。

进入微信公众平台公众号的首页,选择开发者中心,点击进入:

 微信公众平台开发之开发者原理

这里我的已经配置和启用完毕了,界面如上图所示。你首先做的是点击配置,在配置中你需要填写四个内容:URL、Token、EncodingAESKey、消息加解密方式,URL就是你的服务器的URL,Token就是一个令牌,填写什么都可以不过一定要记住,因为之后要使用,EncodingAESKey选择随机生成即可,加密方式我选择了明文模式,填好了这四项,确定之后可能失败,因为我们忘记了一件事情,就是在自己的服务器中要编写初次验证的代码(这个在例子中会有体现),然后确定配置即可。再选择启用即可启用开发者模式。

 

三、        一个简单的例子

先把测试代码抛出,然后进行讲解:

 

 1 <?php 2 /** 3   * wechat php test 4   * update time: 20150114 5   */ 6  7 //define your token 8 define("TOKEN", "weixin"); 9 $wechatObj = new wechatCallbackapiTest();10 if (isset($_GET['echostr'])) {11     $wechatObj->valid();12 }else{13     $wechatObj->responseMsg();14 }15 16 class wechatCallbackapiTest17 {18     public function valid()19     {20         $echoStr = $_GET["echostr"];21 22         //valid signature , option23         if($this->checkSignature()){24             echo $echoStr;25             exit;26         }27     }28 29     public function responseMsg()30     {31         //get post data, May be due to the different environments32         $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];33 34           //extract post data35         if (!empty($postStr)){36                 37                 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);38                 $fromUsername = $postObj->FromUserName;39                 $toUsername = $postObj->ToUserName;40                 $keyword = trim($postObj->Content);41                 $time = time();42                 $textTpl = "<xml>43                             <ToUserName><![CDATA[%s]]></ToUserName>44                             <FromUserName><![CDATA[%s]]></FromUserName>45                             <CreateTime>%s</CreateTime>46                             <MsgType><![CDATA[%s]]></MsgType>47                             <Content><![CDATA[%s]]></Content>48                             <FuncFlag>0</FuncFlag>49                             </xml>";             50                 if(!empty( $keyword ))51                 {52                       $msgType = "text";53                     $contentStr = "Welcome to wechat world!";54                     $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);55                     echo $resultStr;56                 }else{57                     echo "Input something...";58                 }59 60         }else {61             echo "";62             exit;63         }64     }65         66     private function checkSignature()67     {68         $signature = $_GET["signature"];69         $timestamp = $_GET["timestamp"];70         $nonce = $_GET["nonce"];71         $token = TOKEN;72         $tmpArr = array($token, $timestamp, $nonce);73         sort($tmpArr, SORT_STRING);74         $tmpStr = implode( $tmpArr );75         $tmpStr = sha1( $tmpStr );76         77         if( $tmpStr == $signature ){78             return true;79         }else{80             return false;81         }82     }83 }84 85 ?>

 

 我之前定义的Token是“weixin”所以在代码中也要定义相应的Token,有了之前的原理说明我们知道,如果是在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数(signature、timestamp、nonce、echostr),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。我们通过GET中是否含echostr来判断是不是首次提交验证申请,如果是,我们调用$wechatObj->valid()来验证消息的真实性,验证的方法在前面已经提到过,具体的代码在checkSignature()中。

如果消息并不是提交验证申请,那么,我们调用$wechatObj->responseMsg()来回应用户发送的文本消息,回应的文本是“Welcome to wechat world!”。

下面简要的说一下responseMsg()这个函数,它主要功能是用户发送非空的文本,返回给用户一个文本“Welcome to wechat world!”:

1. 获取post数据,存入$postStr中;

2. 如果非空,解析postStr,存入对象postStr,存入对象postObj中;

3. 通过postObj获取postObj获取fromUsername(发送方)、toUsername(接收方)、toUsername(接收方)、keyword(关键字)、$time(时间);

说到这里,不得不提一下微信端的服务器A和我们自己的服务器B之间发送的消息是怎样的,绝不仅仅是用户在客户端发送的字符串,而是XML数据包的格式,下面是一个例子:

 

<xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName> 
    <CreateTime>1348831860</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[this is a test]]></Content>
    <FuncFlag>0</FuncFlag></xml>
 
标签依次记录接收方、发送方、创建时间、消息类型、消息内容。无论是A发送给B,还是B发送给A都是以此格式发送,当B准备好数据发送给A时,B的发送方就是之前的接收方,接收方就是之前的发送方,时间不变,类型也是text,内容成为“Welcome to wechat world!”,对应的代码就是:
 
 1 $fromUsername = $postObj->FromUserName; 2 $toUsername = $postObj->ToUserName; 3 $keyword = trim($postObj->Content); 4 $time = time(); 5 $textTpl = "<xml> 6            <ToUserName><![CDATA[%s]]></ToUserName> 7            <FromUserName><![CDATA[%s]]></FromUserName> 8            <CreateTime>%s</CreateTime> 9            <MsgType><![CDATA[%s]]></MsgType>10            <Content><![CDATA[%s]]></Content>11            <FuncFlag>0</FuncFlag>12            </xml>";             13 if(!empty( $keyword ))14 {15   $msgType = "text";16   $contentStr = "Welcome to wechat world!";17   $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);18     echo $resultStr;19 }else{20      echo "Input something...";21 }

 

xml格式的信息就好比填空题试卷,A填完之后发给B,B修改填空题的答案之后再发给A,开发者要做的就是处理接受的数据得到新的数据,并把新的数据填到试卷上。

 

代码写完之后发布在服务器B上,然后配置好微信公众平台,使得微信平台服务器A和服务器B相互连接。启用开发者模式,客户端发送任何文本消息就可以接收到“Welcome to wechat world!”的信息啦。其他形式的消息也是如此,只不过更改一下XML的格式即可。

 


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程