2.Node.js access_token的获取、存储及更新
一、写在前面的话
上一篇文章中,我们使用 Node.js 成功的实现了接入微信公众平台功能。在这篇文章中,我们将实现微信公众平台一个非常重要的参数 access_token ,它是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用 access_token。
在开始之前,让我们先按捺住自己激动的心情、调整好呼吸,因为我们要将上一篇文章的代码重新整理一下。一个好的项目结构,更能有助于我们理清业务逻辑以及将来维护代码的便捷。OK!
二、整理项目结构
1.打开我们的项目,并在项目中添加文件夹,命名为 wechat ,如图:
2.在 wechat 文件夹中添加文件并命名为 wechat.js。wechat.js 主要用于封装开发微信公众平台的所有方法。首先我们构建这个模块的结构,代码如下:
'use strict' //设置为严格模式//构建 WeChat 对象 即 js中 函数就是对象
var WeChat = function(config){//设置 WeChat 对象属性 configthis.config = config;//设置 WeChat 对象属性 tokenthis.token = config.token;
}//暴露可供外部访问的接口
module.exports = WeChat;
严格模式:是在 ECMAScript 5 中引入的概念。严格模式是为 Javascript 定义了一种解析与执行模型。
module.exports :暴露接口用于外部操作。实际上我们定义模块后,使用 node.js 的 require 引用时,node.js 会自动在我们定义的模块外层加入以下代码
/*** exports module.exports 的一个简短的引用* require 用于引入模块* module 当前模块的引用* __filename 当前模块的文件名* __dirname 当前模块的目录名*/
(function (exports, require, module, __filename, __dirname) {//自定义模块的代码块
})();
相信对于有过 javascript 开发经验的同学,上面的代码并不陌生。我们可以将它理解为一个闭包,是一个匿名方法的调用,避免污染全局变量。
小知识:
在上面的代码中,除了我们所使用的 module.exports 对象,还有另一个用于暴露接口的 变量 exports (官方文档将 module.exports 称为对象,exports 称为 属性,我在这里也就这样称呼了),那么 module.exports 与 exports 有什么区别呢?
module.exports 对象是由模块系统创建的,exports 变量是在模块的文件级别作用域内有效的,它在模块被执行前被赋于 module.exports 的值。——来自Node.js官方文档
也就是说 exports 是 module.exports 的引用,而 module.exports 才是真正用于暴露接口的对象。 exports 赋值的所有属性与方法都赋值给了 module.exports 对象。
如果 module.exports 与 exports 将值赋值给了相同的属性,则按照赋值的先后顺序,取最后一个赋值;如果我们给 module.exports 赋值的是一个对象,则会覆盖 exports 的所有方法与属性。
因此我们在暴露接口的使用上,如果只是单一属性或方法的话,建议使用exports.属性/方法,要是导出多个属性或方法或使用对象构造方法,建议使用 module.exports。
具体详解可以点击查看该文章 -> Module.exports和exports的区别
3.为 WeChat 对象添加一个方法 auth,并将 app.js 中的验证方法粘贴进去
'use strict' //设置为严格模式const crypto = require('crypto'); //引入加密模块//构建 WeChat 对象 即 js中 函数就是对象
var WeChat = function(config){//设置 WeChat 对象属性 configthis.config = config;//设置 WeChat 对象属性 tokenthis.token = config.token;
}/*** 微信接入验证*/
WeChat.prototype.auth = function(req,res){//1.获取微信服务器Get请求的参数 signature、timestamp、nonce、echostrvar signature = req.query.signature,//微信加密签名timestamp = req.query.timestamp,//时间戳nonce = req.query.nonce,//随机数echostr = req.query.echostr;//随机字符串//2.将token、timestamp、nonce三个参数进行字典序排序var array = [this.token,timestamp,nonce];array.sort();//3.将三个参数字符串拼接成一个字符串进行sha1加密var tempStr = array.join('');const hashCode = crypto.createHash('sha1'); //创建加密类型 var resultCode = hashCode.update(tempStr,'utf8').digest('hex'); //对传入的字符串进行加密//4.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信if(resultCode === signature){res.send(echostr);}else{res.send('mismatch');}
}//暴露可供外部访问的接口
module.exports = WeChat;
4.整理 app.js 文件的中的代码,如下:
const express = require('express'), //express 框架 wechat = require('./wechat/wechat'), config = require('./config');//引入配置文件var app = express();//实例express框架var wechatApp = new wechat(config); //实例wechat 模块//用于处理所有进入 3000 端口 get 的连接请求
app.get('/',function(req,res){wechatApp.auth(req,res);
});//监听3000端口
app.listen(3000);
嗯!这样代码看着是不是舒服多了呢。
剩下的就是去微信公众平台接入验证了,在上一篇文章中有详细的教程,这里我就不再演示了
三、access_token的获取、存储及更新
1.微信文档步骤
在开始码代码之前,我们依然是先理清实现的思路,在开始编写实现代码。打开 微信帮助文档 ,点击左侧菜单中的开始开发,点击其子菜单获取access_token,如图:
通过上面的 API 的描述,我们总结出以下步骤:
- 实现 https Get 请求
- 获取 access_token 并存储 如果 当前 access_token 过期则更新
2.access_token的获取、存储及更新 代码实现
整理好思路后我们就按照上一节的步骤去实现。通过帮助文档我们将用于请求微信API 的请求地址与参数,存放到 config.json 文件。
其中 appid 与 secret 两个参数 位于 微信公众平台 左侧菜单的基本配置中,如图:
开发者密码 点击重置,用手机微信扫面二维码后便可得到。config.json 代码如下
{"token":"wechat","appID":"wx154f********764da","appScrect":"59de4266*******8dbe9de4b798cd372","apiDomain":"https://api.weixin.qq.com/","apiURL":{"accessTokenApi":"%scgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"}
}
由于微信 API 请求连接的域名是公用的,我们将它提出来,在请求地址中使用 %s(字符串) 占位符占位。
微信所有请求连接都是 https 协议,很幸运的是 Node.js 系统包中为我们提供了 https 的包,由于后面的请求会多次用到 https ,因此我们将它封装为一个公用的方法,以便以后的使用,再次打开 wechat.js 在构造方法中,引入 https 模块,并在构造函数内部添加 requestGet 方法
//用于处理 https Get请求方法this.requestGet = function(url){return new Promise(function(resolve,reject){https.get(url,function(res){var buffer = [],result = "";//监听 data 事件res.on('data',function(data){buffer.push(data);});//监听 数据传输完成事件res.on('end',function(){result = Buffer.concat(buffer,buffer.length).toString('utf-8');//将最后结果返回resolve(result);});}).on('error',function(err){reject(err);});});}
提示:
npm 提供了很多用于请求的工具包,比如 request ( 安装命令 npm install request ) 等。这里我只是用系统包去做请求处理。
由于 https 是异步请求的,我在这里面使用了 ES6 的 Promise 对象 。
完成了 requestGet方法后,我们的第1步骤也就完成了。下面开始第2步,获取 access_token 并存储 如果 当前 access_token 过期则更新。
在这之前我是想将 access_token 的存储位置依然放在 config.json 文件中,由于 access_token 在更新后 需要将文件重写,可能容易造成 config.json 文件的格式的紊乱,因此在 wechat 中重新创建一个 accessToken.json 文件用于存储 access_token
{"access_token":"","expires_time":0
}
其中 access_token 用于存储 我们 GET 请求后access_token 的值,expires_time 用于存储 access_token 的过期时间,保存为时间戳。
在 wechat.js 引入 fs 模块用于操作文件、util 工具模块用于处理占位符、 accessToken.json 文件
'use strict' //设置为严格模式const crypto = require('crypto'), //引入加密模块https = require('https'), //引入 htts 模块util = require('util'), //引入 util 工具包
accessTokenJson = require('./access_token'); //引入本地存储的 access_token//构建 WeChat 对象 即 js中 函数就是对象
var WeChat = function(config){//设置 WeChat 对象属性 configthis.config = config;//设置 WeChat 对象属性 tokenthis.token = config.token;//设置 WeChat 对象属性 appIDthis.appID = config.appID;//设置 WeChat 对象属性 appScrectthis.appScrect = config.appScrect;//设置 WeChat 对象属性 apiDomainthis.apiDomain = config.apiDomain;//设置 WeChat 对象属性 apiURLthis.apiURL = config.apiURL;//用于处理 https Get请求方法this.requestGet = function(url){return new Promise(function(resolve,reject){https.get(url,function(res){var buffer = [],result = "";//监听 data 事件res.on('data',function(data){buffer.push(data);});//监听 数据传输完成事件res.on('end',function(){result = Buffer.concat(buffer,buffer.length).toString('utf-8');//将最后结果返回resolve(result);});}).on('error',function(err){reject(err);});});}
}
在 wechat.js 添加获取 access_token 的方法 getAccessToken
/*** 获取微信 access_token*/
WeChat.prototype.getAccessToken = function(){var that = this;return new Promise(function(resolve,reject){//获取当前时间 var currentTime = new Date().getTime();//格式化请求地址var url = util.format(that.apiURL.accessTokenApi,that.apiDomain,that.appID,that.appScrect);//判断 本地存储的 access_token 是否有效if(accessTokenJson.access_token === "" || accessTokenJson.expires_time < currentTime){that.requestGet(url).then(function(data){var result = JSON.parse(data); if(data.indexOf("errcode") < 0){accessTokenJson.access_token = result.access_token;accessTokenJson.expires_time = new Date().getTime() + (parseInt(result.expires_in) - 200) * 1000;//更新本地存储的fs.writeFile('./wechat/access_token.json',JSON.stringify(accessTokenJson));//将获取后的 access_token 返回resolve(accessTokenJson.access_token);}else{//将错误返回resolve(result);} });}else{//将本地存储的 access_token 返回resolve(accessTokenJson.access_token); }});
}
在 app.js 中添加新的监听链接用于测试 我们获取的token
//用于请求获取 access_token
app.get('/getAccessToken',function(req,res){wechatApp.getAccessToken().then(function(data){res.send(data);});
});
这样我们就大功告成了!
文章源代码:https://github.com/SilenceHVK/wechatByNode 。对文章有不正确之处,请给予纠正。github源代码请顺手给个 Star,最后感谢您的阅读。
文章目录:
1.Node.js 接入微信公众平台开发
2.Node.js access_token的获取、存储及更新
3.Node.js 自定义微信菜单
4.Node.js 微信消息管理
转载于:https://www.cnblogs.com/hvkcode/p/6941121.html
2.Node.js access_token的获取、存储及更新相关推荐
- node.js基础:数据存储
无服务器的数据存储 内存存储 var http = require('http'); var count = 0; //服务器访问次数存储在内存中 http.createServer(function ...
- MySQL sku 数据批量导入_求node.js中mysql商品sku批量更新解决方案
前提:不使用循环 1.sku具备添加.删除.修改功能,绑定数据sku sku:[ { goods_id: "1MJlrjS17jQ", id: 103, inventory: &q ...
- Node.JS 根据时间戳获取年月日时分秒
/*** 获取当前时间戳(秒)*/ function getNowSceond(){return Math.floor(Date.now() / 1000); }/*** 根据时间戳获取年,月,日,时 ...
- 基于node.js+MongoDB+elementui的分页功能更新优化
一.准备分页组件. 1.1分页组件 src-->components-->Pagination-->index.vue <template><div class=& ...
- 4.Node.js 微信消息管理
一.写在前面的话 当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应. 消息推送也是 ...
- 1.Node.js 接入微信公众平台开发
一.写在前面的话 Node.js是一个开放源代码.跨平台的JavaScript语言运行环境,采用Google开发的V8运行代码,使用事件驱动.非阻塞和异步输入输出模型等技术来提高性能,可优化应用程 ...
- 【Node.js 微信公众号实战】1.Node.js 接入微信公众平台开发
文章目录: 1.Node.js 接入微信公众平台开发 2.Node.js access_token的获取.存储及更新 3.Node.js 自定义微信菜单 ...
- 【Node.js 微信公众号实战】3.Node.js 自定义微信菜单
文章目录: 1.Node.js 接入微信公众平台开发 2.Node.js access_token的获取.存储及更新 3.Node.js 自定义微信菜单 ...
- Node.js获取mac网卡地址
一.关于getmac node.js没有直接获取mac网卡地址的模块,此时我们需要借助于第三方模块getmac.getmac 可以帮助我们 获取当前机器上的mac地址.gatmac 下载地址为:htt ...
- NGINX配置基于Node.js服务的负载均衡服务器
NGINX配置基于Node.js服务的负载均衡服务器 本部署指南说明了如何使用NGINX开源和NGINX Plus在Node.js应用程序服务器池之间平衡HTTP和HTTPS通信.本指南中的详细说明适 ...
最新文章
- swoole单台并发php,php swoole 并发多少?
- idrmyimage 技巧_王者荣耀公孙离2000场-心得技巧,教你究极进阶!
- 代码审计——命令执行
- 以管理员身份运行IJ
- 单元测试junit参数_使用Junit参数在更少的时间内编写更好的单元测试
- eclipse maven打包_我的Java Web之路47 - 使用Maven改造租房网工程
- Linux中如何使用命令修改文件所属用户组
- Web自动化测试中使用groovy实现页面的对象化
- CF573E Bear and Bowling 贪心、分块、凸包
- 光盘文件导入服务器,web服务器 光盘文件
- VS 2019 打包安装应用
- 搜索邻近计算机打印机,在活动目录中设置和管理发布打印机
- 惊悚片 VS 恐怖片
- unity 查找游戏中隐藏的物体
- mysql语句将两列合并一列_mysql – SQL选择将两列合并为一列
- OpenCL——OpenCL的基本介绍
- 计算机及应用成绩表,Excel的基本应用—制作成绩表_计算机软件及应用_IT计.ppt...
- 简单聊聊FPGA的一些参数——后篇
- 51单片机运用数组和if条件语句完成流水灯和蜂鸣器同步
- dotnet 进行二进制差分压缩文件
热门文章
- Go基础-go的源码文件以及常用命令
- R语言堆叠占比柱状图_R语言执行单因素方差分析及多重比较
- c语言打字游戏程序设计报告,2016打字游戏程序设计报告.doc
- linux磁盘常用操作命令
- python做自动化控制postman_Python自动化学习笔记(1)认识接口测试以及postman、Charles工具简单应用...
- 统计图源代码_openlayers4 入门开发系列结合 echarts4 实现统计图(附源码下载)
- java 权限url权限_Java秒杀系统实战系列~整合Shiro实现用户登录认证
- 智能家居规模发展尚需时日
- Java检查日期格式是否正确
- Eclipse Egit 安装