概覽
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.js
里wxShare
里添加自己的分享內容 npm run dev
- 打開微信開發者工具調試
npm run build
- 將域名配置時下載的txt文件放到dist文件夾下
- 上傳到服務器
pm2 start www.js
啟動服務- 在微信里打開連接分享給好友測試
- 擴展:修改/src/component/wxconfig.js中的jsApiList數組,添加想要使用的微信api
WIKI
我們在微信網頁開發的時候需要通過后端返回的微信簽名數據加以前端的配置才能使用微信提供的分享,圖像,音頻等api接口。這里我們就用前后端分離的思想,拿分享到朋友圈為例,使用node來完成這一過程
下圖沒有使用js-sdk開發的頁面在微信里分享樣式
接下來我們一步步來實現
步驟一:綁定域名
先登錄微信公眾平台進入“公眾號設置”的“功能設置”里填寫“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" , // 分享圖標
});
在配置正確的情況下就可以實現配置分享標題描述和圖片了,並且微信提供的可用接口都可以實現。
tips
- 在微信開發者工具中調試
- appid和secret一定要正確
- 域名一定是備案的
- 綁定域名需要的放在服務器上的txt位置一定要正確