koa-session是一个简单的Koa会话(session)中间件。默认为基于cookie的会话,并支持外部存储。
需要Node 8.0.0或更高版本才能支持async/await。
安装
npm install koa-session
注意
为了确保set-cookie值在HTTP规范中有效,6.X将默认cookie密钥从koa:sess
更改为koa.sess
。请看issue。如果您希望与以前的版本兼容,可以手动设置配置项config的key
值为koa:sess
。
范例
const session = require('koa-session');
const Koa = require('koa');
const app = new Koa();
/** 用于加密 cookie, signed 为 true 时必填 ! 数组中如果多于一个项, 则会用于密钥轮换。 */
app.keys = ['some secret hurr'];
const CONFIG = {
key: 'koa.sess', /** (string) cookie 中 sessionId 的格式 (默认 koa.sess) */
/** (number || 'session') session 最大存活周期, 单位 ms (默认1天) */
/** 如果值为'session' 表示何时会话/浏览器关闭,何时会话过期 */
/** 注意:如果会话cookie被盗,该cookie将永远不会过期 */
maxAge: 86400000,
autoCommit: true, /** (boolean) 是否自动提交报头headers:自动将 session 及 sessionid 提交至 header 返回给客户端。 当触发 manuallyCommit 时失效 (默认true) */
overwrite: true, /** (boolean) 是否可覆盖 (默认true) */
httpOnly: true, /** (boolean) 是否httpOnly: 防止XSS攻击, 防止恶意脚本代码劫持 session (默认true) */
signed: true, /** (boolean) 是否应用签名 (default true) */
rolling: false, /** (boolean) 是否每次响应刷新 session 有效期 (默认 false) */
renew: false, /** (boolean) 是否在会话即将过期时更新会话,这样我们就可以始终保持用户登录 (默认false)*/
secure: true, /** (boolean) 是否只在 https 中传输 (默认 false)*/
sameSite: null, /** (string) session cookie sameSite options (默认为空,不要设置它) */
};
app.use(session(CONFIG, app));
// 若配置项全部采用默认, 可以这样写: app.use(session(app));
app.use(ctx => {
// 忽略 favicon
if (ctx.path === '/favicon.ico') return;
let n = ctx.session.views || 0;
ctx.session.views = ++n;
ctx.body = n + ' views';
});
app.listen(3000);
console.log('listening on port 3000');
译者注:
httpOnly设置为true,表明该cookies在客户端上不可访问(即document.cookie
访问不到该cookie)。更详细的讲解请看这篇文章《HttpOnly是个什么鬼》
API
配置项
cookie的name由key
配置项控制,默认为“koa.sess”
格式。所有其他选项都传递给ctx.cookies.get()
和ctx.cookies.set()
,以能够使你控制安全性(security)、域(domain)、路径(path)和其他设置中的签名。
自定义编码/解码( encode/decode)支持
使用配置项的encode
和decode
字段可以自定义编、解码方法。
钩子Hooks
- valid():在使用之前验证会话值。
- beforeSave():在保存会话之前触发的钩子
外部会话存储
默认情况下,会话存储在cookie中,但它有一些缺点:
- 会话未经加密存储在客户端
- 浏览器cookie有长度限制
可以通过配置项将会话内容存储在外部存储(Redis, MongoDB或其他数据库)中。使用实现以下三个方法存储(必须是异步函数)的对象:
- get(key, maxAge, { rolling, ctx }):通过key获取会话对象的方法。
- set(key, sess, maxAge, { rolling, changed, ctx }):设置会话对象的key和maxAge(以毫秒为单位)的方法。
- destroy(key, {ctx}):销毁秘钥key会话的方法。
一旦你传递了配置项store
。存储、会话存储依赖于你的外部存储——如果外部存储宕机,你就无法访问会话。仅在必要时使用外部会话存储,避免将会话用作缓存,保持会话精简,并尽可能将其存储在cookie中!
生成外部session id的方式由配置项的genid(ctx)
控制,默认为uuid.v4()
。
如果要为所有外部session id添加前缀,可以使用配置项的prefix
字段。如果配置项中存在genid(ctx)
,则prefix
不起作用。
如果会话存储需要来自上下文的数据或实用程序,可以在配置项上设置ContextStore
,ContextStore
必须是一个声明上述三个实例方法(get、set、destroy)的类。new ContextStore(ctx)
将对每个请求执行。
译者注:关于session的外部存储可以看这篇文章《koa-session的简单使用|第二篇》(使用的redis数据库)或者koa-session2插件。
事件
当会话过期或无效时,Koa-session将在koa的app
对象上触发事件:
- session:missed:无法从外部存储获取会话值时触发。
- session:invalid:会话值无效时触发。
- session:expired:会话值过期时触发。
自定义外部密钥Key
外部密钥key默认使用cookie,但您可以通过配置项externalKey
来自定义外部密钥方法。该字段必须是一个包含以下两种方法的对象:
- get(ctx):获取外部密钥key的方法。
- set(ctx, value):设置外部密钥key的方法。
Session#isNew
如果会话是新的返回true
。
if (this.session.isNew) {
// user has not logged in
} else {
// user has already logged in
}
Session#maxAge
获取会话最大存活周期。
Session#maxAge=
设置会话最大存活周期。
Session#externalKey
获取会话外部密钥key,只有当外部会话存储存在时才存在。
Session#save()
保存会话(不管它是否被填充)。
Session#manuallyCommit()
缺省情况下,会话头是自动提交的。如果autoCommit设置为false,则使用此选项。
销毁会话
要销毁会话,只需将其设置为null:
this.session = null;