赞
踩
访问https://open.weixin.qq.com 根据指引进行注册申请,申请流程相对比较麻烦,需要耐心等待审核
进入‘管理中心->创建第三方平台’
!基本信息将显示在授权页被用户看到,请认真填写
修改平台审核成功后,仅对测试公众号生效,届时再提交“覆盖现网全网发布状态”并审核成功后,才可影响现网
根据第三方平台需要的接口权限进行选择,需要注意:
- 修改平台审核成功后,仅对测试公众号生效,届时再提交“覆盖现网全网发布状态”并审核成功后,才可影响现网;
- 在修改平台时,若有权限的增加,则视为一次平台升级,已授权用户使用老权限不受任何影响,但使用新权限需要用户再次进行授权页进行升级授权,此时注意引导用户重新授权
授权流程相关
授权发起页
:即引导用户进入授权页面的入口页面的域名(后面开发部分会详细介绍)
授权测试公众号列表
:要填写公众号的原始ID,‘微信公众平台->公众号设置->原始ID’
授权事件接收URL
:用于接收微信的各种通知,包括授权成功、取消授权、授权更新以及每十分钟推送的component_verify_ticket(后面开发部分会详细介绍)
授权后代公众号实现业务
如果有过公众号开发经验这部分就相对比较容易理解了,基本上与公众号开发的配置相同(‘微信公众平台->基本配置->服务器配置’),可以参考公众号开发准备这篇文章。
公众号消息与事件接收URL
这一项要配置一个通配符$APPID$
,不同的公众号事件推送时,这个通配符会自动替换为对应的公众号的AppID
其它
这个IP列表要填写公网IP,我使用的是阿里云ESC云服务器
使用 Node.js
进行的服务端开发,数据库使用 Mysql
,ES7
语法,使用Koa2
框架。具体框架结构参考使用Koa2搭建web项目这篇文章(一定要看,不然后面的代码会看不懂)。下面会按流程逐步完成第三方平台后台的开发
为了篇幅工整,所有的工具类(XXXUtil.js)均放在最后列举
<完成本文2.3中的 授权事件接收URL
的开发>
在公众号第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket(重要字段类似于密码)。将字段存入数据库定期刷新,component_verify_ticket、component_access_token以及component_auth_code存储在同一个表中,数据表component
结构如下:
id | component_ticket | component_access_token | component_auth_code |
---|
【component.js】
const xmlUtil = require("./../utils/xmlUtil.js");
const componentService = require('./../service/componentService.js');
//Be called every 10 minutes to refresh component_verify_ticket by wechat
//Be called when authorized
//Be called when unauthorized
//Be called when refresh
var handleComponentMessage = async (ctx, next) => {
let requestString = ctx.data;
let requestMessage = xmlUtil.formatMessage(requestString.xml);
let query = ctx.query;
/**
* Checking whether access_token and pre_auth_code
* need to be refreshed according to component_verify_ticket
* access_token need to be refreshed every 2 hours
* pre_auth_code need to be refreshed every 30 minutes
*/
let result = await componentService.handleComponentMessage(requestMessage, query);
ctx.response.body = 'success';
}
... ...
module.exports = {
'POST /handleComponentMessage' :handleComponentMessage
};
【componentService.js】
const xml2js = require('xml2js');
const xmlUtil = require("./../utils/xmlUtil.js");
const wechatCrypto = require('./../utils/cryptoUtil.js');
const http = require('./../utils/httpUtils.js');
//analyze the decrypted message (xml => json)
var resolveMessage = messageXML => {
var message = new Promise((resolve, reject) => {
xml2js.parseString(messageXML, {trim: true}, (err, result) => {
var message = xmlUtil.formatMessage(result.xml);
resolve(message);
});
}).then(function(message) {
return message;
});
return message;
};
var handleComponentMessage = async (requestMessage, query) => {
let signature = query.msg_signature;
let timestamp = query.timestamp;
let nonce = query.nonce;
logger.debug("Receive messasge from weixin \nsignature: " + signature + "\ntimestamp: " + timestamp + "\nnonce: " + nonce);
//Create cryptor object for decrypt message
let cryptor = new wechatCrypto(真实的token, 真实的encodingAESKey, 真实的第三方平台appID);
let encryptMessage = requestMessage.Encrypt;
let decryptMessage = cryptor.decrypt(encryptMessage);
logger.debug('Receive messasge from weixin decrypted :' + JSON.stringify(decryptMessage));
var message = await resolveMessage(decryptMessage.message);
let infoType = message.InfoType;
if(infoType == 'component_verify_ticket') {
let ticket = message.ComponentVerifyTicket;
//query the component_verify_ticket, component_access_token and component_auth_code
... ...
//TODO 将拿到的ticket更新存储到数据表component中
} else if(infoType == 'authorized') {
//TODO authorized
} else if(infoType == 'unauthorized') {
//TODO unauthorized
} else if(infoType == 'refresh') {
//TODO refresh
}
return '';
}
由于两个属性都需要定期刷新,所以我做了一个定时任务,定时刷新这两个字段并存入数据表component
中
【refresh.js】
const schedule = require('node-schedule');
const http = require('./../utils/httpUtils.js');
//refresh component_access_token every 1 hour
var refreshComponentAccessToken = async function() {
var component = 读取表component;
var ticket = component.component_ticket;
if(ticket == null || ticket == undefined || ticket == '') {
return;
}
var access_token = component.component_access_token;
var auth_code = component.component_auth_code;
var componentTokenPostData = {
component_appid : 第三方appID,
component_appsecret : 第三方appSecret,
component_verify_ticket : ticket
};
var https_options = {
hostname : 'api.weixin.qq.com',
path : '/cgi-bin/component/api_component_token',
method : 'post'
};
var component_access_token_result = await http.doHttps_withdata(https_options, componentTokenPostData);
var access_token_json = JSON.parse(component_access_token_result);
logger.debug('Refresh component_access_token result: ' + component_access_token_result);
if(access_token_json.errcode != undefined) {
return;
}
access_token = access_token_json.component_access_token;
//TODO 将拿到的access_token 更新存储到数据表component中
}
//refresh pre_auth_code every 20 minutes
var refreshComponentAuthCode = async function() {
var component = 读取表component;
var ticket = component.component_ticket;
var access_token = component.component_access_token;
if(access_token == null || access_token == undefined || access_token == '') {
return;
}
var access_token_times = component.component_access_token_times;
var auth_code = component.component_auth_code;
var auth_code_times = component.component_auth_code_times;
var componentAuthCodePostData = {
component_appid : config.component.appID
};
var https_options = {
hostname : 'api
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。