Nivelle 开拓视野冲破艰险看见世界 身临其境贴近彼此感受生活

微信服务号开发之原理

2017-09-02
nivelle

微信处理原理

image

通信协议为:HTTP,微信服务器与自定义服务器通信的数据的格式是xml.

1. 验证服务器

公众平台提交信息后微信服务器发送get请求到自定义服务器地址,并且有四个参数

参数 描述
signature 微信加密签名
timestamp 时间戳
nonce 随机数
echostr 随机字符串校验,

开发者通过校验signature对请求进行校验,若确认此次get请求来自微信服务器,请原样返回echostr参数内容,则接入生效,否则接入失败.signature结合了开发者填写的token参数和请求中的timestamp,nonce .

加密/校验流程:

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

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

  • 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

消息加解密方式有三种:

  • 明文模式
  • 兼容模式
  • 安全模式

重点说一下安全模式:

首先请注意,开发者在接收消息和事件时,都需要进行消息加解密(某些事件可能需要回复,回复时也需要先进行加密)。但是,通过API主动调用接口(包括调用客服消息接口发消息)时,不需要进行加密。

具体消息加解密的做法是,当关注者与授权公众号交互时,公众号第三方平台将接收到响应的消息推送,时间推送.为保证安全性,将对此过程进行两个措施:

1.在接收已经授权公众号消息和事件的url中,增加两个参数:encrypt_type(加密类型,为aes)和msg_signature(消息体签名,用于验证消息体的正确)

2.postdata中的XML体,将使用第三方平台申请是的接收消息的加密symmetric_key(也称为EncodingAESKey)来进行加密

具体步骤:

  • 实例化对象,传入第三方平台的token,appid,EncodingAESKey
 WXBizMsgCrypt pc = new WXBizMsgCrypt(token,EncodingAESKey,appId);

  • 解密:调用pc的DecryptMsg函数,参数包括:msg_signature,timetamp,nonce和postdata.前三个参数可以从接收已授权公众号消息和事件的URL中获得,postData为POST过来的数据包内容. 加密模式下的数据体如下:
encrypt_msg = 
<xml>
<ToUserName></ToUserName>
<Encrypt></Encrypt>
</xml>

若解密成功,则会返回解密后的数据体:

<xml>
<ToUserName></ToUserName>
<FromUserName></FromUserName>
<CreateTime>1411035097</CreateTime>
<MsgType></MsgType>
<Content></Content>
<MsgId>6060349595123187712</MsgId>
</xml>

  • 加密:调用pc的EncryptMsg接口,传入需要回复给微信公众平台的res_msg,timestamp,nonce

若需要回复给用户的消息入下:

res_msg = 
<xml> 
<ToUserName></ToUserName>
<FromUserName></FromUserName>
<CreateTime>1411034505</CreateTime>
<MsgType></MsgType>
<Content></Content>
<FuncFlag>0</FuncFlag>
</xml>

则加密成功后,返回的加密后的消息体如下:

<xml>
<Encrypt>
<![CDATA[LDFAmKFr7U/RMmwRbsR676wjym90byw7+hhh226e8bu6KVYy00HheIsVER4eMgz/VBtofSaeXXQBz6fVdkN2CzBUaTtjJeTCXEIDfTBNxpw/QRLGLq qMZHA3I+JiBxrrSzd2yXuXst7TdkVgY4lZEHQcWk85x1niT79XLaWQog+OnBV31eZbXGPPv8dZciKqGo0meTYi+fkMEJdyS8OE7NjO79vpIyIw7hMBtEXPBK/tJGN5m5SoAS 6I4rRZ8Zl8umKxXqgr7N8ZOs6DB9tokpvSl9wT9T3E62rufaKP5EL1imJUd1pngxy09EP24O8Th4bCrdUcZpJio2l11vE6bWK2s5WrLuO0cKY2GP2unQ4fDxh0L4ePmNOVFJ wp9Hyvd0BAsleXA4jWeOMw5nH3Vn49/Q/ZAQ2HN3dB0bMA+6KJYLvIzTz/Iz6vEjk8ZkK+AbhW5eldnyRDXP/OWfZH2P3WQZUwc/G/LGmS3ekqMwQThhS2Eg5t4yHv0mAIei 07Lknip8nnwgEeF4R9hOGutE9ETsGG4CP1LHTQ4fgYchOMfB3wANOjIt9xendbhHbu51Z4OKnA0F+MlgZomiqweT1v/+LUxcsFAZ1J+Vtt0FQXElDKg+YyQnRCiLl3I+GJ/c xSj86XwClZC3NNhAkVU11SvxcXEYh9smckV/qRP2Acsvdls0UqZVWnPtzgx8hc8QBZaeH+JeiaPQD88frNvA==]]> </Encrypt>
<MsgSignature></MsgSignature>
<TimeStamp>1411034505</TimeStamp>
<Nonce></Nonce>
</xml>

用户向公众号发送消息时,公众号方收到的消息发送者是一个OpenID,是使用用户微信号加密后的结果,每个用户对每个公众号有一个唯一的OpenID。

由于开发者经常有需在多个平台(移动应用、网站、公众帐号)之间共通用户帐号,统一帐号体系的需求,微信开放平台(open.weixin.qq.com)提供了UnionID机制。开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个应用(移动应用、网站应用和公众帐号,公众帐号只有在被绑定到微信开放平台帐号下后,才会获取UnionID),可通过获取用户基本信息中的UnionID来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的UnionID是唯一的。换句话说,同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的。详情请在微信开放平台的资源中心-移动应用开发-微信登录-授权关系接口调用指引-获取用户个人信息(UnionID机制)中查看。


评论