-
Notifications
You must be signed in to change notification settings - Fork 93
Store
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
.
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 passinterval
option as milliseconds, if you don't need the interval, passnoInterval: 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
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
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
.
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({...}),
})