Nodejs微信公众号开发

简介: 概览keyvalue项目名称node微信公众号开发项目描述使用node编写接口,前后端分离获取签名数据开发者leinov发布日期2018-11-07仓库github地址安装&使用下载git clone git@github.

概览

key value
项目名称 node微信公众号开发
项目描述 使用node编写接口,前后端分离获取签名数据
开发者 leinov
发布日期 2018-11-07
仓库 github地址

安装&使用

下载
git clone git@github.com:leinov/node-weixin-api.git

npm install
开发
  • 在微信公众号后台配置域名白名单
  • server/weixin/wx.js里添加自己的appid secret
  • src/index/index.jswxShare里添加自己的分享内容
  • npm run dev
  • 打开微信开发者工具调试
  • npm run build
  • 将域名配置时下载的txt文件放到dist文件夹下
  • 上传到服务器
  • pm2 start www.js启动服务
  • 在微信里打开连接分享给好友测试
  • 扩展:修改/src/component/wxconfig.js中的jsApiList数组,添加想要使用的微信api

WIKI

我们在微信网页开发的时候需要通过后端返回的微信签名数据加以前端的配置才能使用微信提供的分享,图像,音频等api接口。这里我们就用前后端分离的思想,拿分享到朋友圈为例,使用node来完成这一过程

下图没有使用js-sdk开发的页面在微信里分享样式

image

接下来我们一步步来实现

步骤一:绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

在添加域名时需要下载一个txt文件放到服务器web可访问的根目录 比如http://www.leinov.com/xxx.txt 可访问的静态根目录,比如node的静态文件设置的是public文件,就放public下

备注:登录后可在“开发者中心”查看对应的接口权限,看是否有分享朋友圈等权限

步骤二: 引入微信JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.4.0.js 也可以直接下载到本地目录引入

步骤三:通过config接口注入权限验证配置(第六步详解)

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

我们使用微信的所有接口都需要有在引入wx js-sdk和配置config的前提下
下面我们主要讲解如何通过node来获取微信签名的config的数据。

步骤四:生成签名config数据

步骤三所需要的数据需要通过签名算来生成,下面是生成签名数据的步骤

  • 1,通过公众号的appid和secret获取access_token
  • 2.根据access_token获取ticket票据
  • 3.根据微信提供node生成签名算法(需要ticket,url参数来返回config数据

这里要强调是secret一定要写在后端,决不能暴露在前端,这也是为什么需要用接口返回数据的原因。

获取签名config数据完整代码 server/wx.js
/*********************************************************************************
 * @file: 返回微信开发需要的config数据
 * @desc:
 *      1,通过appid和secret获取access_token
 *      2.根据access_token获取ticket
 *      3.根据ticket和url(访问的页面地址由接口传过来 )通过sgin加密返回前度需要用到的config数据
 * @ahthor: leinov
 * @usedate:2018-11-07
**********************************************************************************/

const request = require("request");
const Base64 = require("js-base64").Base64;
const sign = require("./sign.js"); //微信提供在开发文档可以找到下载到本地
const base={
    appid:"****",//公众号appid
    secret:"****", // 公众号secret (重要不要暴露在前端)
    wxapi:"https://api.weixin.qq.com/cgi-bin"
};
/**
 * 根据appid,secret获取access_token
 */
function  getAccessToken(){
    return new Promise((resolve, reject)=>{
        request.get(`${base.wxapi}/token?grant_type=client_credential&appid=${base.appid}&secret=${base.secret}`, function (error, response, body) {
            if(error!==null){
                reject("获取access_token失败 检查getAccessToken函数");
            }
            resolve(JSON.parse(body));
        });
    });
}

/**
 * 根据access_token获取api_ticket
 *
 * @param  {String} access_token
 * @return {Promise}
 */
function getTicket(access_token){
    return new Promise((resolve,reject)=>{
        request.get(`${base.wxapi}/ticket/getticket?access_token=${access_token}&type=jsapi`, function (error, response, body) {
            if(error!==null){
                reject("获取api_ticket失败 检查getTicket函数");
            }
            resolve(JSON.parse(body));
        });
    });
}

/**
 * 根据api_ticket和url通过加密返回所有config数据
 *
 * @param  {String} href
 * @return {Object} configdata
 */
async function getConfigData(href){
    let configData;
    try{
        const accessTokenData = await getAccessToken();
        const ticketData = await getTicket(accessTokenData.access_token);
        const decodeHref = Base64.decode(href);
        configData = sign(ticketData.ticket,decodeHref);
        configData.appid = base.appid;
    }catch(err){
        //打印错误日志
        console.log(err);
        configData = {};
    }
    return configData;
}

module.exports = getConfigData;

这里使用到了request来请求微信接口,sign.js是微信提供的node签名算法,自己可以下载,通过微信接口请求以及node签名算法就可以获取到如下签名数据。

  timestamp: ,  // 生成签名的时间戳
  nonceStr: '', // 生成签名的随机串
  signature: '',// 签名

第五步:编写接口返回config数据

上面wx.js已经获得数据, 接下来我们用node编写接口返回数据。注意下面的href,href是前端传回的用来生成签名的,而且这个网页地址的域名一定是在设置里加入白名单了的。

var express = require("express");
var app = express();
var getConfigData = require("./server/wx.js");
var port = "3000";

//获取微信配置数据接口
app.get("/wxconfigdata", function(req, res){ //获取配置
    let href = req.query.href;//get获取前端传来的base64网页地址
    getConfigData(href).then((data)=>{
        res.send(JSON.stringify(data));
    });
});

var server = http.createServer(app);
server.listen(port);
server.on("listening", onListening);

这样就启动了一个3000端口的服务
我们通过访问 "http://localhost:3000/wxconfigdata" 就可以拿到数据,但这个数据是不正确的,因为locahost跟在设置里的白名单域名不匹配,所以在开发时我们要放到测试服务器里测试。

步骤六:前端请求获取签名数据

/*********************************************************************************
 * @file: src/wxconfig.js 通过接口获取微信config数据
 * @ahthor: leinov
 * @usedate:2018-11-07
**********************************************************************************/

import { Base64 } from "js-base64";
const axios = require("axios");

/**
 * 页面调用微信分享方法
 *
 * @param  {Object} obj      分享的标题,描述,图片等
 * @param  {type} callback
 * @return {type}
 */
function wxShare(obj,callback){
    const href = Base64.encode(location.href);
    //base64当前页面地址传给后端生成签名
    axios.get(`${location.origin}/wxconfigdata?href=${href}`).then((res)=>{
        wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: res.data.appid, // 必填,公众号的唯一标识
            timestamp: res.data.timestamp, // 必填,生成签名的时间戳
            nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
            signature: res.data.signature,// 必填,签名,见附录1
            jsApiList: ["onMenuShareTimeline","onMenuShareAppMessage"] // 必填,需要使用的JS接口列表,所有JS接口列表见文档
        });
        shareConfig(obj,callback);
    }).catch((err)=>{
        shareConfig({},callback);
    });
}

function shareConfig(obj,callback){
    wx.ready(function(){
        //分享到朋友圈
        wx.onMenuShareTimeline({
            title:  obj.timelinetitle ? obj.timelinetitle : obj.title , // 分享标题
            link: obj.link, // 分享链接
            imgUrl: obj.imgUrl ? obj.imgUrl :"" , // 分享图标
            success: function () {
                if (typeof callback === "function"){
                    callback();
                }
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });

        // 分享给微信好友
        wx.onMenuShareAppMessage({
            title: obj.title, // 分享标题
            desc: obj.desc, // 分享描述
            link: obj.link, // 分享链接
            imgUrl: obj.imgUrl ? obj.imgUrl:"",
            success: function () {
                if (typeof callback === "function"){
                    callback();
                }
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
    });
}

export default wxShare;

步骤七:页面使用

假设我们使用的是react 在react 打包入口js文件里调用配置即可

import wxShare from "../component/wxconfig.js";
wxShare({
    title: "驾多多-小程序时代的驾校管理系统", // 分享标题
    desc:"驾多多驾校管理系统。帮助驾校在互联网时代,零门槛使用小程序工具,提升招生量、提升服务能力、降低运营成本,是为驾校提供人、财、物及业务办理的综合管理系统。", // 分享描述
    link: location.href, // 分享链接
    imgUrl:"https://***/jiaddwxicon.png" , // 分享图标
});
在配置正确的情况下就可以实现配置分享标题描述和图片了,并且微信提供的可用接口都可以实现。

image

tips

  • 在微信开发者工具中调试
  • appid和secret一定要正确
  • 域名一定是备案的
  • 绑定域名需要的放在服务器上的txt位置一定要正确

参考

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
目录
相关文章
|
4月前
|
小程序 PHP
微信公众号开发(一)打通服务器与微信之间的通信
说来惭愧PHP做了这么久,好像就没有从头开发过一个微信公众号,这次刚好有机会从头接入开发一个完整的公众号,也不能说完整,但是这些微信的接口我基本上都试一试~看看大概是什么情况。 首先:打通服务器与微信之间的通信。
55 0
|
1月前
|
开发者
微信公众平台开发基本配置
微信公众平台开发基本配置
88 0
|
1月前
|
移动开发 JavaScript
微信公众号H5开发,在微信浏览器打开H5,无法一键下载图片
微信公众号H5开发,在微信浏览器打开H5,无法一键下载图片
39 0
|
3月前
|
XML Go 数据格式
【微信公众号开发】基于golang的公众号开发——接入消息自动回复接口
【微信公众号开发】基于golang的公众号开发——接入消息自动回复接口
134 0
|
4月前
|
小程序 PHP 开发者
微信公众号开发(八)生成带参数二维码,以及将二维码下载至本地
微信的二维码真是个神奇的东西。在我们开发中,应用也是很多~ 用户扫描带场景值(参数)二维码时,可能推送以下两种事件:
64 1
|
4月前
|
XML 移动开发 小程序
微信公众号开发(七)微信h5跳转小程序及小游戏示例
最近公司做活动,需要从h5页面跳转至微信小游戏。 当时接到这个需求的时候,就在想,这玩意能相互跳转么? 后来百度了一下,还真行。
115 1
|
4月前
|
小程序 PHP
微信公众号开发(六)微信支付(发红包、企业支付到零钱)需要证书请求示例
这里最主要的就是curlpost请求的时候需要带上证书。否则请求会失败。
59 0
|
4月前
|
XML JSON 小程序
微信公众号开发(四)获取用户信息
获取用户信息,微信公众号提供了两种方式:
52 0
|
4月前
|
JSON 小程序 前端开发
微信公众号开发(三)设置底部菜单
填写access_token值,关于如何获取accesstoken值,请参见《微信公众号开发(二)微信公众号的access_token》 最后,将想要设置菜单的json写入body中。
111 0
|
4月前
|
JSON 小程序 数据库
微信公众号开发(二)微信公众号的access_token
微信对用户使用开放了很多的功能,如:自定义菜单接口、客服接口、获取用户信息接口、用户分组接口、群发接口,但是为了保证用户访问这些功能相对安全,每次访问都需要带上一个秘钥去验证身份。那么这个秘钥就是access_token。
69 0