Skip to content

Simple session middleware for Express

License

Notifications You must be signed in to change notification settings

zimplexing/session

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

express-session

安装

 $ npm install express-session 

API

 var session = require('express-session')

session(配置)

使用相应的配置来创建一个session中间件

提示 除了session ID之外,session的数据不会自己储存到cookie中,session的数据会被存在服务器端

警告 在服务器端session故意默认储存在内存中,这不是为了生产环境而设计的.这样在大多数情况下会泄露内存,does not scale past a single process, and is meant for debugging and developing.

更多的储存列表,详情请看: compatible session stores

配置

express-session在配置对象中可以接受这些属性

cookie

设置cookie中的session ID.cookie更多不同参数的信息,请参考下面"cookie配置"小节,其默认的参数为{ path: '/', httpOnly: true, secure: false, maxAge: null }

genid

用来生成一个新的session ID的函数,提供一个返回通常用来做session ID的字符串的方法.当生成ID时,你如果想将某些值赋值给req,那么req作为该方法的第一个参数.

该默认值是一个使用uid-safe依赖库生成ID的函数.

提示 注意生成唯一的ID,这样你的session才不会产生冲突

app.use(session({
  genid: function(req) {
    return genuuid() // use UUIDs for session IDs
  },
  secret: 'keyboard cat'
}))
name

session ID的cookie名可以在设置在响应头中(可以在请求头中读取).

默认值是 'connect.sid'.

提示如果你有多个app运行在同一个主机名上(只是主机名相同,比如localhost或者127.0.0.1;如果有不同的方案和端口的话,就没有必要命名不同的主机名了),这时你需要区分每一个session cookie了.最简单的方法是为每一个app设置一个不同的名称.

proxy

当设置了安全的cookie后,可以充分相信反向代理(可以通过"X-Forwarded-Proto"头)

默认值 undefined.

  • true 使用 "X-Forwarded-Proto" 头
  • false 连接都只考虑安全性,所有的头都会被忽略 如果这是一个TLS/SSL连接的话
  • undefined 使用express中设置的"trust proxy"
resave

即使在请求中session没有进行任何修改,也会强制session重新存储一遍. 取决于你的存储这是非常有必要的,但是它会产生一个竞争的情况,当一个客户端向你的服务器发送两条并行的请求时,一个请求中session发生改变时,当另一个请求结束时,这个session可能会被重写,即使这个session没有做任何修改,也可能会被重写(这种情况也取决于你使用的存储).

默认值是 true,但是这个默认值已经被弃用了,这个默认值在之后会被修改.请在研究这个设置后,根据你的使用情况来选择.通常情况下,你会选择false.

那我怎么知道,这个是否对我的存储有必要呢?最好的方式是检查你的存储是否有touch这个方法.如果有,你可以安全设置resave:false.如果没有touch这个方法,你的储存会在被存储的session上设置一个过期时间,然后你可能需要resave:true.

rolling

会在每一个响应上,强制session设置一个cookie识别码.过期时间会被重置为original maxAge,并且重置倒计时.

默认值是 false.

提示 当这个被设置为true,但是saveUninitialized设置为false时,一个响应的session没有被初始化,cookie是不会被设置的.

saveUninitialized

强制将未初始化的session存储到内存中,未初始化的session是指一个全新的session且没有被修改过的.在使用登录session,减少服务器内存的使用,或者遵守在设置cookie前获取许可的规范时,将其设置为false是一个不错的选择.而且还能对客户端发送多个没有session请求的所形成竞争情况有所帮助.

默认值是true,但是使用默认值已经被弃用,默认值在之后也将被修改,请研究这个设置之后,根据你的使用情况来选择

提示 如果你与PassportJS结合使用session的话,在用户认证之后,Passport会增加一个空的Passport对象在session中.这会默认认为session已经被修改,而造成这个session被存储的情况.

secret

Required option

This is the secret used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests.

store

The session store instance, defaults to a new MemoryStore instance.

unset

Control the result of unsetting req.session (through delete, setting to null, etc.).

The default value is 'keep'.

  • 'destroy' The session will be destroyed (deleted) when the response ends.
  • 'keep' The session in the store will be kept, but modifications made during the request are ignored and not saved.

Cookie options

Note Since version 1.5.0, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser.

Please note that secure: true is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using secure: true, you need to set "trust proxy" in express:

var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

For using secure cookies in production, but allowing for testing in development, the following is an example of enabling this setup based on NODE_ENV in express:

var app = express()
var sess = {
  secret: 'keyboard cat',
  cookie: {}
}

if (app.get('env') === 'production') {
  app.set('trust proxy', 1) // trust first proxy
  sess.cookie.secure = true // serve secure cookies
}

app.use(session(sess))

The cookie.secure option can also be set to the special value 'auto' to have this setting automatically match the determined security of the connection. Be careful when using this setting if the site is available both as HTTP and HTTPS, as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This is useful when the Express "trust proxy" setting is properly setup to simplify development vs production configuration.

By default cookie.maxAge is null, meaning no "expires" parameter is set so the cookie becomes a browser-session cookie. When the user closes the browser the cookie (and session) will be removed.

req.session

To store or access session data, simply use the request property req.session, which is (generally) serialized as JSON by the store, so nested objects are typically fine. For example below is a user-specific view counter:

// Use the session middleware
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))

// Access the session as req.session
app.get('/', function(req, res, next) {
  var sess = req.session
  if (sess.views) {
    sess.views++
    res.setHeader('Content-Type', 'text/html')
    res.write('<p>views: ' + sess.views + '</p>')
    res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>')
    res.end()
  } else {
    sess.views = 1
    res.end('welcome to the session demo. refresh!')
  }
})

Session.regenerate()

To regenerate the session simply invoke the method. Once complete, a new SID and Session instance will be initialized at req.session.

req.session.regenerate(function(err) {
  // will have a new session here
})

Session.destroy()

Destroys the session, removing req.session; will be re-generated next request.

req.session.destroy(function(err) {
  // cannot access session here
})

Session.reload()

Reloads the session data.

req.session.reload(function(err) {
  // session updated
})

Session.save()

Save the session back to the store, replacing the contents on the store with the contents in memory (though a store may do something else--consult the store's documentation for exact behavior).

This method is automatically called at the end of the HTTP response if the session data has been altered (though this behavior can be altered with various options in the middleware constructor). Because of this, typically this method does not need to be called.

There are some cases where it is useful to call this method, for example, long- lived requests or in WebSockets.

req.session.save(function(err) {
  // session saved
})

Session.touch()

Updates the .maxAge property. Typically this is not necessary to call, as the session middleware does this for you.

req.session.id

Each session has a unique ID associated with it. This property will contain the session ID and cannot be modified.

req.session.cookie

Each session has a unique cookie object accompany it. This allows you to alter the session cookie per visitor. For example we can set req.session.cookie.expires to false to enable the cookie to remain for only the duration of the user-agent.

Cookie.maxAge

Alternatively req.session.cookie.maxAge will return the time remaining in milliseconds, which we may also re-assign a new value to adjust the .expires property appropriately. The following are essentially equivalent

var hour = 3600000
req.session.cookie.expires = new Date(Date.now() + hour)
req.session.cookie.maxAge = hour

For example when maxAge is set to 60000 (one minute), and 30 seconds has elapsed it will return 30000 until the current request has completed, at which time req.session.touch() is called to reset req.session.maxAge to its original value.

req.session.cookie.maxAge // => 30000

req.sessionID

To get the ID of the loaded session, access the request property req.sessionID. This is simply a read-only value set when a session is loaded/created.

Session Store Implementation

Every session store must be an EventEmitter and implement specific methods. The following methods are the list of required, recommended, and optional.

  • Required methods are ones that this module will always call on the store.
  • Recommended methods are ones that this module will call on the store if available.
  • Optional methods are ones this module does not call at all, but helps present uniform stores to users.

For an example implementation view the connect-redis repo.

store.all(callback)

Optional

This optional method is used to get all sessions in the store as an array. The callback should be called as callback(error, sessions).

store.destroy(sid, callback)

Required

This required method is used to destroy/delete a session from the store given a session ID (sid). The callback should be called as callback(error) once the session is destroyed.

store.clear(callback)

Optional

This optional method is used to delete all sessions from the store. The callback should be called as callback(error) once the store is cleared.

store.length(callback)

Optional

This optional method is used to get the count of all sessions in the store. The callback should be called as callback(error, len).

store.get(sid, callback)

Required

This required method is used to get a session from the store given a session ID (sid). The callback should be called as callback(error, session).

The session argument should be a session if found, otherwise null or undefined if the session was not found (and there was no error). A special case is made when error.code === 'ENOENT' to act like callback(null, null).

store.set(sid, session, callback)

Required

This required method is used to upsert a session into the store given a session ID (sid) and session (session) object. The callback should be called as callback(error) once the session has been set in the store.

store.touch(sid, session, callback)

Recommended

This recommended method is used to "touch" a given session given a session ID (sid) and session (session) object. The callback should be called as callback(error) once the session has been touched.

This is primarily used when the store will automatically delete idle sessions and this method is used to signal to the store the given session is active, potentially resetting the idle timer.

Compatible Session Stores

The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :)

★ cassandra-store An Apache Cassandra-based session store.

★ cluster-store A wrapper for using in-process / embedded stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2 and other multi-core embedded devices).

★ connect-azuretables An Azure Table Storage-based session store.

★ connect-couchbase A couchbase-based session store.

★ connect-dynamodb A DynamoDB-based session store.

★ connect-mssql A SQL Server-based session store.

★ connect-monetdb A MonetDB-based session store.

★ connect-mongo A MongoDB-based session store.

★ connect-mongodb-session Lightweight MongoDB-based session store built and maintained by MongoDB.

★ connect-pg-simple A PostgreSQL-based session store.

★ connect-redis A Redis-based session store.

★ connect-memcached A memcached-based session store.

★ connect-session-knex A session store using Knex.js, which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.

★ connect-session-sequelize A session store using Sequelize.js, which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.

★ express-mysql-session A session store using native MySQL via the node-mysql module.

★ connect-sqlite3 A SQLite3 session store modeled after the TJ's connect-redis store.

★ express-nedb-session A NeDB-based session store.

★ level-session-store A LevelDB-based session store.

★ mssql-session-store A SQL Server-based session store.

★ nedb-session-store An alternate NeDB-based (either in-memory or file-persisted) session store.

★ sequelstore-connect A session store using Sequelize.js.

★ session-file-store A file system-based session store.

★ session-rethinkdb A RethinkDB-based session store.

Example

一个使用express-session的简单例子,来演示用户存储一个页面视图.

var express = require('express')
var parseurl = require('parseurl')
var session = require('express-session')

var app = express()

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true
}))

app.use(function (req, res, next) {
  var views = req.session.views

  if (!views) {
    views = req.session.views = {}
  }

  // get the url pathname
  var pathname = parseurl(req).pathname

  // count the views
  views[pathname] = (views[pathname] || 0) + 1

  next()
})

app.get('/foo', function (req, res, next) {
  res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
})

app.get('/bar', function (req, res, next) {
  res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
})

License

MIT

About

Simple session middleware for Express

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%