Skip to content
jason edited this page Feb 28, 2018 · 4 revisions

Store provides a better way and apis to store your jssdk signatures and oauth tokens, etc... to anywhere you want, e.g memory, file, database..., with the help of Store, you don't need to get token, jsapi_ticket... from wechat server every single time, which is limited by wechat server, so we need to cache them on our application.
Store can also automatically refresh the token if the target token or ticket was expired, but also provides a way to manually refresh the token used together with JSSDK and OAuth.

Built in Stores

  1. Store
  2. FileStore
  3. MongoStore
  4. Create Custom Store

Store

The Store class is the base class for all the other custom stores, both FileStore and MongoStore are subclass of the Store class, you also need to extend Store if you want to create your own store, and implement the apis needed. If you just use new Store() as the store for JSSDK or OAuth, it will just use memory as the place to store info, which is dis-encouraged, you need a persistent store like FileStore or MongoStore or your own store to persist.

Below are the apis you need to implement when create your custom store,

All the apis are Promise based!!!

const Store = require('wechat-jssdk').Store;
class CustomStore extends Store {}
  • @constructor, new CustomStore(options), the default Store will setup an simple interval task to flush cached token info to the persistent store every specified time(default every 10 minutes), but you can set your own interval by pass interval option as milliseconds, if you don't need the interval, pass noInterval: true to disable it.
  • getGlobalToken(), get the global token from store.
  • updateGlobalToken (newTokenInfo), update the global token to store.
  • getSignature(url), get url signature for the current page.
  • saveSignature (url, signatureInfo), save new signature to store.
  • updateSignature(url, newInfo), update the existing url signature, like if it's expired.
  • isSignatureExisting(url), check if the signature for the passed url exists.
  • getOAuthAccessToken(key), get cached oauth token by the unique key.
  • saveOAuthAccessToken(key, info), save new oauth token.
  • updateOAuthAccessToken(key, newInfo), update the oauth token, like if it's expired.
  • flush(), flush in memory info to persistent store.
  • destroy(), destroy the current store instance, do some clearing.

FileStore

FileStore is the default store being used internally if you didn't pass any custom store when initialize.
FileStore specific options:

const FileStore = require('wechat-jssdk').FileStore;
new FileStore({
  //where to save the json file, default: ${process.cwd()}/wechat-info.json
  fileStorePath: './my-wechat-info.json', 
})

MongoStore

MongoStore will store in memory info to mongodb,
MongoStore specific options, and use it in Wechat:

const Wechat = require('wechat-jssdk');
const MongoStore = Wechat.MongoStore;
//use it
const mongoStore = new MongoStore({
  dbHost: 'mongodb_host', //default: "127.0.0.1"
  dbPort: 'mongodb_post', //default: "27017"
  dbName: 'your_db_name', //default: "wechat"
  dbAddress: 'full_db_connection_uri', //pass your full uri, the three options above will be ignored.
  dbOptions: {}, //extra options passed to mongoose
  limit: 10, //how many url signature and oauth token items should be initialized from db, default: 20
});
//now use it in wehcat object
const wx = new Wechat({
  appId: 'xxx',
  ...
  store: mongoStore, //use mongoStore for the instance
})

Three collections/models will be used: GlobalToken, Signature, OAuthToken.

Create Custom Store

You can also create your custom store to persist token info anywhere, e.g. Redis, by doing that, you will need to extend the base Store class:

const Store = require('wechat-jssdk').Store;
class CustomStore extends Store {
  constructor (options) {
    super(options);
    ....
  }
  // implement the apis in base Store class, e.g.
  getSignature (url) { 
    return super.getSignature(url) //get from cache first
      .then((sig) => {
        if(!_.isEmpty(sig)) {
          return Promise.resolve(sig);
        }
        // now you may try get it from like redis
        return this.getFromRedis(url)
          .then((sig) => {
            if(!_.isEmpty(sig)) {
              debug('got signature from db');
              //store it in memory, so that it can be retrieved from memory directly next time
              //without getting it from redis again
              this.store.urls[url] = sig;
            }
            return Promise.resolve(sig);
          });
      });
  }
  ....
  flush () {
    return Promise.all([
        this.flushGlobalToken(),
        this.flushSignatures(),
        this.flushOAuthTokens(),
      ])
      .then(() => super.flush())
      .catch(() => super.flush())
      ;
  }
  destroy () {
    this.closeRedisConns(); //some method to clean connections
    super.destroy();
    debug('redisStore destroyed!');
  }
}
//use it your wechat object
const wx = new Wechat({
  appId: 'abc', 
  ...
  store: new CustomStore({...}),
})
Clone this wiki locally