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
pm2 start www.js
啓動服務webpack4
react16
es6
node
js-sdk
git
|-- node-weixin-api //項目 |-- dist //編譯生產目錄 |-- index |-- index.css |-- index.js |-- index.html |-- xxx.txt // 微信域名綁定識別文件 |-- node_modules |-- server // node文件 |-- sign.js //公衆號文檔提供簽名算法 |-- wx.js //獲取簽名數據文件 |-- src //開發目錄 |-- index |-- images/ |-- js/ |-- app.js |-- b.js |-- index.scss |-- index.js //頁面js入口文件 |-- template.html // webpack html-webpack-plugin 插件生成html模板 |-- style.sass //公共sass |-- webpackConfig //webpack配置 |-- package.json |-- .gitignore |-- webpack.config.js //webpack配置文件 |-- www.js //生產啓動程序
咱們在微信網頁開發的時候須要經過後端返回的微信簽名數據加之前端的配置才能使用微信提供的分享,圖像,音頻等api接口。這裏咱們就用先後端分離的思想,拿分享到朋友圈爲例,使用node來完成這一過程css
接下來咱們一步步來實現html
先登陸微信公衆平臺進入「公衆號設置」的「功能設置」裏填寫「JS接口安全域名」。前端
在添加域名時須要下載一個txt文件放到服務器web可訪問的根目錄 好比http://www.leinov.com/xxx.txt 可訪問的靜態根目錄,好比node的靜態文件設置的是public文件,就放public下node
備註:登陸後可在「開發者中心」查看對應的接口權限,看是否有分享朋友圈等權限react
在須要調用JS接口的頁面引入以下JS文件,(支持https):http://res.wx.qq.com/open/js/... 也能夠直接下載到本地目錄引入webpack
全部須要使用JS-SDK的頁面必須先注入配置信息,不然將沒法調用(同一個url僅需調用一次,對於變化url的SPA的web app可在每次url變化時進行調用,目前Android微信客戶端不支持pushState的H5新特性,因此使用pushState來實現webios
wx.config({ debug: true, // 開啓調試模式,調用的全部api的返回值會在客戶端alert出來,若要查看傳入的參數,能夠在pc端打開,參數信息會經過log打出,僅在pc端時纔會打印。 appId: '', // 必填,公衆號的惟一標識 timestamp: , // 必填,生成簽名的時間戳 nonceStr: '', // 必填,生成簽名的隨機串 signature: '',// 必填,簽名 jsApiList: [] // 必填,須要使用的JS接口列表 });
咱們使用微信的全部接口都須要有在引入wx js-sdk和配置config的前提下
下面咱們主要講解如何經過node來獲取微信簽名的config的數據。git
步驟三所須要的數據須要經過簽名算來生成,下面是生成簽名數據的步驟es6
這裏要強調是secret必定要寫在後端,決不能暴露在前端,這也是爲何須要用接口返回數據的緣由。github
/********************************************************************************* * @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: '',// 簽名
上面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" , // 分享圖標 });