一、微信服务器与我们服务器的交流
微信开发者拥有自己的服务器,在我们服务器上可以与微信服务器进行交流。既然可以交流,那就必定需要前提条件(微信认证),也就是说,只有自己的服务器与微信服务器进行认证通过后,才能与他交流。如何进行认证?
1. 接口认证
接口的认证是token验证,微信服务器会发送一个get请求给我们在公众号配置的接口,如http://xxxx/weixin/api ,这个请求带了如下参数
然后,微信规定我们
1)将token、timestamp、nonce三个参数进行字典序排序 (token是在微信后台配置的)
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
通过上述三步,如果加密后的字符串与signature是相同的,那么认证成功,我们就给微信返回 echostr 接口结束。
nodejs代码如下:
app.get('/weixin/api', function (req, res) { var query = req.query var signature = query.signature var nonce = query.nonce var timestamp = query.timestamp var echostr = query.echostr // token在配置文件里 var str = [weixinConfig.token, timestamp, nonce].sort().join('') // 利用sha1模块进行sha1加密 var sha = sha1(str) if (sha === signature) { res.send(echostr) } else { res.send('wrong wrong wrong') } })
这样,我们就完成了微信接口认证。我们可以与微信进行交流了。
2. 接收微信推送内容
每一个微信动态(如:我们推送一篇图文给某个用户,或者用户点击了某个菜单),微信服务器都会给我们推送事件消息。微信服务器会以post请求的方式以xml格式推送给我们数据。因此,微信认证的路由我们还需要定义post接口来接收来自微信的推送消息。
2.1.情景模拟
1. 某一个时间,我们需要给某用户发送一个图文消息,发送成功后,微信服务器收到发送成功的响应,则微信服务器就会将这个动作的响应发给我们服务端,告诉我们结果,然后我们做出相应的行为。
2. 用户点击了某个图文菜单,微信服务器接收到请求,则微信服务器将这个请求消息发送给我们服务端,让我们做出进一步相应的行为(返回给用户图文)。
这两种情况微信都是以xml格式发送给我们数据的。我们需要接收。每一个微信服务器发送的post请求,我们都必须做相应的回复,比如用户点击图文菜单,我们要给用户发送一个图文,我们只需要以微信规定的的xml格式send给微信服务器的这个请求就可以了。
2.2 微信推送消息的类型(xml格式中的Event内容)
1. click:事件类型,又分自定义事件和微信端事件。
2. text:文本类型。
下面是nodejs的接口代码,用了xml2js的xml解析模块。weixinAutoMessage是个对象,下面包含了所有动作的接口。
app.post('/weixin/api', function (req, res) { //获取xml数据 req.on("data", function(data) { //将xml解析 console.log('收到微信消息的xml:' + data) parser.parseString(data.toString(), function(err, result) { var body = result.xml; var messageType = body.MsgType[0]; if(messageType === 'event') { // 如果是自定义事件,那么就取事件名为body.EventKey的第一个参数 var eventName = body.Event[0] === 'CLICK' ? body.EventKey[0]: body.Event[0]; console.log('事件类型是:' + eventName); weixinAutoMessage[eventName](body, res) }else if(messageType === 'text') { weixinAutoMessage.responseMessage(body, res); } }); });})
二、access_token的获取
对于一个话都说不清楚的我,感觉上面写的自己都看不懂。语言组织能力太差了。不过这个access_token应该好懂的。
access_token介绍:这个东西是一个调用微信api时认证用的,每一个微信api都需要加上这个东西。下面称atoken。
微信规定,开发者需要从微信服务器上获取一个叫atoken的字串,并保存到自己的数据库中,微信端的atoken会每2小时更新一次,也就是说,我们服务器需要获取一次atoken后的2小时候再次获取一次atoken,保证我们存储的atoken与微信端保持一致,因为我们调用微信接口需要atoken认证。
这个atoken获取很简单了,看文档
我们调用这个微信接口就可以了,我们需要传递的就是appid secret,这两个都是在微信公众号后台的参数。我们调用这个接口,微信就返回一个最新的atoken,这里说一下2小时的计算是在你获取atoken后开始计算的。
如果你在9点获取了atoken, 微信就开始计算2小时后失效,也就是11点失效。
如果你在10点又获取了一次atoken,微信就重新计算2小时,也就是12点后失效。
因此根据特性,我们在一次获取atoken后,在2小时内重新获取即可。
getAccessToken () { var url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential' + '&appid=' + weixinConfig.appId + '&secret=' + weixinConfig.appSecret// request模块发送请求request({ uri: url, method: 'GET', timeout: 10000, followRedirect: true, maxRedirects: 10, json: true}, function (err, res,body) { // ... 进行存储操作 })}
定时获取便是开启一个定时器了
// 一小时获取一次setInterval(getAccessToken, 60 * 60 * 1000)
总结
access_token 我这样1小时获取一次,并且保证了重启服务器后开启新定时器不会超过两小时,为啥我在使用access_token是经常是已经过期!这个问题搞了很久都不知道原因,后来,在每一次使用access_token时都进行一个试探性验证,如果此时access_token失效了,重新获取后再做下一步操作。这是我的方法。但是为什么2小时内access_token失效并不知道。。尴尬。。。。。。
由于并没有专注研究微信公众号开发,可能一些地方是错的,然而我并没有发现。有大佬看到了请指正。
另外附上最新自己搞的网站,还在开发中,不要脸的附上。有看到的同学可以进来看看啊,支持一下: