欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Node.js access_token的獲取、存儲及更新

 更新時間:2017年06月20日 15:23:37   作者:H_VK  
本篇文章主要介紹了Node.js access_token的獲取、存儲及更新 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、寫在前面的話

上一篇文章中,我們使用 Node.js 成功的實現(xiàn)了接入微信公眾平臺功能。在這篇文章中,我們將實現(xiàn)微信公眾平臺一個非常重要的參數(shù) access_token ,它是公眾號的全局唯一接口調(diào)用憑據(jù),公眾號調(diào)用各接口時都需使用 access_token。

在開始之前,讓我們先按捺住自己激動的心情、調(diào)整好呼吸,因為我們要將上一篇文章的代碼重新整理一下。一個好的項目結(jié)構(gòu),更能有助于我們理清業(yè)務(wù)邏輯以及將來維護代碼的便捷。OK?

二、整理項目結(jié)構(gòu)

1.打開我們的項目,并在項目中添加文件夾,命名為 wechat ,如圖:

2.在 wechat 文件夾中添加文件并命名為 wechat.js。wechat.js 主要用于封裝開發(fā)微信公眾平臺的所有方法。首先我們構(gòu)建這個模塊的結(jié)構(gòu),代碼如下:

'use strict' //設(shè)置為嚴格模式

//構(gòu)建 WeChat 對象 即 js中 函數(shù)就是對象
var WeChat = function(config){
  //設(shè)置 WeChat 對象屬性 config
  this.config = config;
  
  //設(shè)置 WeChat 對象屬性 token
  this.token = config.token;
}

//暴露可供外部訪問的接口
module.exports = WeChat;

嚴格模式:是在 ECMAScript 5 中引入的概念。嚴格模式是為 Javascript 定義了一種解析與執(zhí)行模型。

module.exports :暴露接口用于外部操作。實際上我們定義模塊后,使用 node.js 的 require 引用時,node.js 會自動在我們定義的模塊外層加入以下代碼

/**
 * exports module.exports 的一個簡短的引用
 * require 用于引入模塊
 * module  當前模塊的引用
 * __filename 當前模塊的文件名
 * __dirname  當前模塊的目錄名
 */
(function (exports, require, module, __filename, __dirname) {
  //自定義模塊的代碼塊
})();

相信對于有過 javascript 開發(fā)經(jīng)驗的同學(xué),上面的代碼并不陌生。我們可以將它理解為一個閉包,是一個匿名方法的調(diào)用,避免污染全局變量。

小知識:

在上面的代碼中,除了我們所使用的 module.exports 對象,還有另一個用于暴露接口的 變量 exports (官方文檔將 module.exports 稱為對象,exports 稱為 屬性,我在這里也就這樣稱呼了),那么 module.exports 與 exports 有什么區(qū)別呢?

module.exports 對象是由模塊系統(tǒng)創(chuàng)建的,exports 變量是在模塊的文件級別作用域內(nèi)有效的,它在模塊被執(zhí)行前被賦于 module.exports 的值。——來自Node.js官方文檔

也就是說 exports 是 module.exports 的引用,而 module.exports 才是真正用于暴露接口的對象。 exports 賦值的所有屬性與方法都賦值給了 module.exports 對象。

如果 module.exports 與 exports 將值賦值給了相同的屬性,則按照賦值的先后順序,取最后一個賦值;如果我們給 module.exports 賦值的是一個對象,則會覆蓋 exports 的所有方法與屬性。

因此我們在暴露接口的使用上,如果只是單一屬性或方法的話,建議使用exports.屬性/方法,要是導(dǎo)出多個屬性或方法或使用對象構(gòu)造方法,建議使用 module.exports。

3.為 WeChat 對象添加一個方法 auth,并將 app.js 中的驗證方法粘貼進去

'use strict' //設(shè)置為嚴格模式

const crypto = require('crypto'); //引入加密模塊

//構(gòu)建 WeChat 對象 即 js中 函數(shù)就是對象
var WeChat = function(config){
  //設(shè)置 WeChat 對象屬性 config
  this.config = config;

  //設(shè)置 WeChat 對象屬性 token
  this.token = config.token;
}

/**
 * 微信接入驗證
 */
WeChat.prototype.auth = function(req,res){
   //1.獲取微信服務(wù)器Get請求的參數(shù) signature、timestamp、nonce、echostr
    var signature = req.query.signature,//微信加密簽名
      timestamp = req.query.timestamp,//時間戳
        nonce = req.query.nonce,//隨機數(shù)
      echostr = req.query.echostr;//隨機字符串

    //2.將token、timestamp、nonce三個參數(shù)進行字典序排序
    var array = [this.token,timestamp,nonce];
    array.sort();

    //3.將三個參數(shù)字符串拼接成一個字符串進行sha1加密
    var tempStr = array.join('');
    const hashCode = crypto.createHash('sha1'); //創(chuàng)建加密類型 
    var resultCode = hashCode.update(tempStr,'utf8').digest('hex'); //對傳入的字符串進行加密

    //4.開發(fā)者獲得加密后的字符串可與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);
});

//監(jiān)聽3000端口
app.listen(3000);

嗯!這樣代碼看著是不是舒服多了呢。機智如我

剩下的就是去微信公眾平臺接入驗證了,在上一篇文章中有詳細的教程,這里我就不再演示了

就是這么懶

三、access_token的獲取、存儲及更新

1.微信文檔步驟

在開始碼代碼之前,我們依然是先理清實現(xiàn)的思路,在開始編寫實現(xiàn)代碼。打開 微信幫助文檔 ,點擊左側(cè)菜單中的開始開發(fā),點擊其子菜單獲取access_token,如圖:

通過上面的 API 的描述,我們總結(jié)出以下步驟:

1.實現(xiàn) https Get 請求

2.獲取 access_token 并存儲 如果 當前 access_token 過期則更新

2.access_token的獲取、存儲及更新 代碼實現(xiàn)

整理好思路后我們就按照上一節(jié)的步驟去實現(xiàn)。通過幫助文檔我們將用于請求微信API 的請求地址與參數(shù),存放到 config.json 文件。

其中 appid 與 secret 兩個參數(shù) 位于 微信公眾平臺 左側(cè)菜單的基本配置中,如圖:

開發(fā)者密碼 點擊重置,用手機微信掃面二維碼后便可得到。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 協(xié)議,很幸運的是 Node.js 系統(tǒng)包中為我們提供了 https 的包,由于后面的請求會多次用到 https ,因此我們將它封裝為一個公用的方法,以便以后的使用,再次打開 wechat.js 在構(gòu)造方法中,引入 https 模塊,并在構(gòu)造函數(shù)內(nèi)部添加 requestGet 方法

//用于處理 https Get請求方法
  this.requestGet = function(url){
    return new Promise(function(resolve,reject){
      https.get(url,function(res){
        var buffer = [],result = "";
        //監(jiān)聽 data 事件
        res.on('data',function(data){
          buffer.push(data);
        });
        //監(jiān)聽 數(shù)據(jù)傳輸完成事件
        res.on('end',function(){
          result = Buffer.concat(buffer,buffer.length).toString('utf-8');
          //將最后結(jié)果返回
          resolve(result);
        });
      }).on('error',function(err){
        reject(err);
      });
    });
  }

提示:

npm 提供了很多用于請求的工具包,比如 request ( 安裝命令 npm install request ) 等。這里我只是用系統(tǒng)包去做請求處理。

由于 https 是異步請求的,我在這里面使用了 ES6 的 Promise 對象 。

完成了 requestGet方法后,我們的第1步驟也就完成了。下面開始第2步,獲取 access_token 并存儲 如果 當前 access_token 過期則更新。

在這之前我是想將 access_token 的存儲位置依然放在 config.json 文件中,由于 access_token 在更新后 需要將文件重寫,可能容易造成 config.json 文件的格式的紊亂,因此在 wechat 中重新創(chuàng)建一個 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' //設(shè)置為嚴格模式

const crypto = require('crypto'), //引入加密模塊
    https = require('https'), //引入 htts 模塊
    util = require('util'), //引入 util 工具包
accessTokenJson = require('./access_token'); //引入本地存儲的 access_token

//構(gòu)建 WeChat 對象 即 js中 函數(shù)就是對象
var WeChat = function(config){
  //設(shè)置 WeChat 對象屬性 config
  this.config = config;
  //設(shè)置 WeChat 對象屬性 token
  this.token = config.token;
  //設(shè)置 WeChat 對象屬性 appID
  this.appID = config.appID;
  //設(shè)置 WeChat 對象屬性 appScrect
  this.appScrect = config.appScrect;
  //設(shè)置 WeChat 對象屬性 apiDomain
  this.apiDomain = config.apiDomain;
  //設(shè)置 WeChat 對象屬性 apiURL
  this.apiDomain = config.apiURL;

  //用于處理 https Get請求方法
  this.requestGet = function(url){
    return new Promise(function(resolve,reject){
      https.get(url,function(res){
        var buffer = [],result = "";
        //監(jiān)聽 data 事件
        res.on('data',function(data){
          buffer.push(data);
        });
        //監(jiān)聽 數(shù)據(jù)傳輸完成事件
        res.on('end',function(){
          result = Buffer.concat(buffer,buffer.length).toString('utf-8');
          //將最后結(jié)果返回
          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 中添加新的監(jiān)聽鏈接用于測試 我們獲取的token

//用于請求獲取 access_token
app.get('/getAccessToken',function(req,res){
  wechatApp.getAccessToken().then(function(data){
    res.send(data);
  });  
});

這樣我們就大功告成了!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用C++為node.js寫擴展模塊

    使用C++為node.js寫擴展模塊

    本文給大家介紹的是在window7下使用C++來給node.js編寫擴展模塊的方法,附上一個簡單的hello實例,有需要的小伙伴可以參考下。
    2015-04-04
  • Electron架構(gòu)深入探究

    Electron架構(gòu)深入探究

    這篇文章主要為大家介紹了Electron架構(gòu)深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 使用Node.js自動生成帶動態(tài)圖表的Word文檔

    使用Node.js自動生成帶動態(tài)圖表的Word文檔

    在現(xiàn)代軟件開發(fā)中,動態(tài)生成?Word?文檔是一項非常常見的需求,本文將結(jié)合Node.js和ECharts實現(xiàn)自動生成帶動態(tài)圖表的Word文檔,感興趣的可以了解下
    2024-03-03
  • nodejs中各種加密算法的實現(xiàn)詳解

    nodejs中各種加密算法的實現(xiàn)詳解

    這篇文章主要給大家介紹了關(guān)于nodejs中各種加密算法的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用nodejs具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • linux 下以二進制的方式安裝 nodejs

    linux 下以二進制的方式安裝 nodejs

    這篇文章主要介紹了linux 下以二進制的方式安裝 nodejs,文中給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • Node.js中的模塊系統(tǒng)介紹

    Node.js中的模塊系統(tǒng)介紹

    這篇文章介紹了Node.js中的模塊系統(tǒng),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • node中使用es6/7/8(支持性與性能)

    node中使用es6/7/8(支持性與性能)

    這篇文章主要介紹了node中使用es6/7/8(支持性與性能),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • Node使用Sequlize連接Mysql報錯:Access denied for user ‘xxx’@‘localhost’

    Node使用Sequlize連接Mysql報錯:Access denied for user ‘xxx’@‘localh

    這篇文章主要給大家介紹了關(guān)于Node使用Sequlize連接Mysql報錯:Access denied for user 'xxx'@'localhost'的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • Node.js 實現(xiàn)簡單小說爬蟲實例

    Node.js 實現(xiàn)簡單小說爬蟲實例

    現(xiàn)在爬蟲在很多web項目中都有應(yīng)用,這篇文章主要介紹了Node.js 實現(xiàn)簡單小說爬蟲實例,有興趣的可以了解一下。
    2016-11-11
  • 淺析Node.js中的內(nèi)存泄漏問題

    淺析Node.js中的內(nèi)存泄漏問題

    這篇文章主要介紹了淺析Node.js中的內(nèi)存泄漏問題,Node.js是使JavaScript應(yīng)用在服務(wù)器端運行的一款框架,需要的朋友可以參考下
    2015-06-06

最新評論