Session

WEB requests are often maintained through the session, ThinkJS through the think-session and Adapter to support the session function.

Configure extensions and Adapter

Modify the extension configuration file src/config/extend.js (src/common/config/extend.js in multi-module project) and add the following configuration:

const session = require('think-session');
module.exports = [
  session
]

Modify the Adapter configuration file src/config/adapter.js (src/common/config/adapter.js in multi-module project) and add the following configuration:

const fileSession = require('think-session-file');

exports.session = {
  type: 'file',
  common: {
    cookie: {
      name: 'thinkjs',
      keys: ['signature key'],
      signed: true
    }
  },
  file: {
    handle: fileSession,
    sessionPath: path.join(think.ROOT_PATH, 'runtime/session')
  }
}

The list of supported session types can be found in the https://github.com/thinkjs/think-awesome#session, where the cookie option is the configuration when the session is set to cookie, and the value is merged with the think.config ('cookie') value. The name field value is the name of the session for the cookie.

Injection method

After adding the think-session extension, the ctx.session and controller.session methods are injected, where controller.session is the wrapper of the ctx.session method and reads the configuration for the current request.

Get the session

module.exports = class extends think.Controller {
  // get the session
  async indexAction() {
    const data = await this.session('name');
  }
}

Set the session

module.exports = class extends think.Controller {
  // set the session
  async indexAction() {
    await this.session('name', 'value');
  }
}

Delete the session

module.exports = class extends think.Controller {
  // delete the whole session
  async indexAction() {
    await this.session(null);
  }
}

FAQ

A request can operate different types of session?

Clearly not. Session data is updated asynchronously, so only one session is allowed for one request.

How to synchronize the session data?

When the session data changes, it won't immediately update to the session container (for performance), but at the end of the request unified update.

this.ctx.res.once('finish', () => {
  this.flush(); // flush the session to the storage container on request
});

How to obtain session corresponding cookie value?

Session corresponding cookie value can't be manually set, but the framework automatically generated by think.uuid. Follow-up Action can generate a cookie by calling this.cookie ('thinkjs') (thinkjs is the session corresponding cookie field name).

How to limit the same account in different terminals login?

In some cases, one account only can be allowed to log in one terminal. If terminal is changed, the previously logged terminal needs to be kicked off. (By default, the same account can be logged in simultaneously with different terminals). At this point, you can use a service to save the correspondence between the user's unique ID and session cookie value. If the same user but different cookies, you are not allowed to log in or kick off the previous session. Such as:

// after the user login successfully
const cookie = this.cookie('thinkjs');
const uid = userInfo.id;
await this.redis.set(`uid-${uid}`, cookie);

// judge the session cookie value is the same when request
const userInfo = await this.session('userInfo');
const cookie = this.cookie('thinkjs');
const saveCookie = await this.redis.get(`uid-${userInfo.id}`);
if(saveCookie && saveCookie !== cookie) {
  // not the last device to log in
}