# Session

因为HTTP协议本身是无状态的,session 提供了一种保存用户请求信息的途径。


# 配置

session 的配置位于 src/config/session.js

  • store: session 的存储介质,默认使用Cookie存储
  • key: 当 storecookie 时,session 保存的 key
  • maxAge: session 的最大过期时间,默认 8640000
  • httpOnly: 是否 httponly,默认 true
  • signed: 是否加签,默认 true
  • autoCommit: 是否自动提交,默认 true

# 操作

获取 Session 变量

request.session().get('key')

获取 Session 变量,不存在时返回默认值

request.session().get('key', 'default')

存储 Session 变量

request.session().set('key', 'value')

判断 Session 变量是否存在

request.session().has('key')

删除一个 Session 变量

request.session().remove('key')

删除所有 Session 变量

request.session().flush()

# 闪存

Session 闪存功能可以将部分 Session 保存到下次请求为止

request.session().flash('key', 'value')

# 存储介质

配置文件提供了 store 配置,用来自定义 Session 存储介质。

下面以 Redis 为例:

我们创建一个 RedisStore 作为存储介质

import * as redis from 'redis';
import { promisify } from 'util';
import { SessionStoreInterface, Application } from '@tiger/common'


export class RedisStore implements SessionStoreInterface {
  // app 实例
  app: Application;
  client: any;

  // 因为存储介质是在容器保存的,所以我们可以在构造函数中直接拿到应用实例
  constructor(app: Application) {
    this.app = app;
  }

  // 初始化存储介质
  // 一般可以在这里做 redis 连接操作
  init () {
    this.client = redis.createClient({
      // redis 配置
    });
    return new Promise((resolve, reject) => {
      this.client.on('connect', () => {
        resolve()
      })
      this.client.on('error', (e) => {
        reject(e)
      })
    })
  }

  async get(id: string) {
    const getAsync = promisify(this.client.get).bind(this.client);
    const res = await getAsync(id);
    if (!res) return null;
    return JSON.parse(res);
  }

  async set(id: string, sess: any, maxAge?: number) {
    const max = typeof maxAge === 'number' ? maxAge : 1000 * 60 * 60 * 24;
    const val = JSON.stringify(sess);
    const setAsync = promisify(this.client.set).bind(this.client);
    const res = await setAsync(id, val, 'PX', max);
    return res;
  }

  async destroy(id: string) {
    const delAsync = promisify(this.client.del).bind(this.client);
    const res = await delAsync(id);
    return res;
  }
}