UNPKG

45.5 kBMarkdownView Raw
1# express-session
2
3[![NPM Version][npm-version-image]][npm-url]
4[![NPM Downloads][npm-downloads-image]][node-url]
5[![Build Status][ci-image]][ci-url]
6[![Test Coverage][coveralls-image]][coveralls-url]
7
8## Installation
9
10This is a [Node.js](https://nodejs.org/en/) module available through the
11[npm registry](https://www.npmjs.com/). Installation is done using the
12[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
13
14```sh
15$ npm install express-session
16```
17
18## API
19
20```js
21var session = require('express-session')
22```
23
24### session(options)
25
26Create a session middleware with the given `options`.
27
28**Note** Session data is _not_ saved in the cookie itself, just the session ID.
29Session data is stored server-side.
30
31**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
32no longer needs to be used for this module to work. This module now directly reads
33and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
34if the `secret` is not the same between this module and `cookie-parser`.
35
36**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
37not designed for a production environment. It will leak memory under most
38conditions, does not scale past a single process, and is meant for debugging and
39developing.
40
41For a list of stores, see [compatible session stores](#compatible-session-stores).
42
43#### Options
44
45`express-session` accepts these properties in the options object.
46
47##### cookie
48
49Settings object for the session ID cookie. The default value is
50`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
51
52The following are options that can be set in this object.
53
54##### cookie.domain
55
56Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
57is set, and most clients will consider the cookie to apply to only the current
58domain.
59
60##### cookie.expires
61
62Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
63By default, no expiration is set, and most clients will consider this a
64"non-persistent cookie" and will delete it on a condition like exiting a web browser
65application.
66
67**Note** If both `expires` and `maxAge` are set in the options, then the last one
68defined in the object is what is used.
69
70**Note** The `expires` option should not be set directly; instead only use the `maxAge`
71option.
72
73##### cookie.httpOnly
74
75Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
76the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
77attribute is set.
78
79**Note** be careful when setting this to `true`, as compliant clients will not allow
80client-side JavaScript to see the cookie in `document.cookie`.
81
82##### cookie.maxAge
83
84Specifies the `number` (in milliseconds) to use when calculating the `Expires`
85`Set-Cookie` attribute. This is done by taking the current server time and adding
86`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
87no maximum age is set.
88
89**Note** If both `expires` and `maxAge` are set in the options, then the last one
90defined in the object is what is used.
91
92##### cookie.partitioned
93
94Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
95attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
96By default, the `Partitioned` attribute is not set.
97
98**Note** This is an attribute that has not yet been fully standardized, and may
99change in the future. This also means many clients may ignore this attribute until
100they understand it.
101
102More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
103
104##### cookie.path
105
106Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
107is the root path of the domain.
108
109##### cookie.priority
110
111Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
112
113 - `'low'` will set the `Priority` attribute to `Low`.
114 - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
115 - `'high'` will set the `Priority` attribute to `High`.
116
117More information about the different priority levels can be found in
118[the specification][rfc-west-cookie-priority-00-4.1].
119
120**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
121This also means many clients may ignore this attribute until they understand it.
122
123##### cookie.sameSite
124
125Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
126By default, this is `false`.
127
128 - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
129 - `false` will not set the `SameSite` attribute.
130 - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
131 - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
132 - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
133
134More information about the different enforcement levels can be found in
135[the specification][rfc-6265bis-03-4.1.2.7].
136
137**Note** This is an attribute that has not yet been fully standardized, and may change in
138the future. This also means many clients may ignore this attribute until they understand it.
139
140**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
141that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
142set to `'none'`. Some web browsers or other clients may be adopting this specification.
143
144##### cookie.secure
145
146Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
147the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
148attribute is not set.
149
150**Note** be careful when setting this to `true`, as compliant clients will not send
151the cookie back to the server in the future if the browser does not have an HTTPS
152connection.
153
154Please note that `secure: true` is a **recommended** option. However, it requires
155an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
156is set, and you access your site over HTTP, the cookie will not be set. If you
157have your node.js behind a proxy and are using `secure: true`, you need to set
158"trust proxy" in express:
159
160```js
161var app = express()
162app.set('trust proxy', 1) // trust first proxy
163app.use(session({
164 secret: 'keyboard cat',
165 resave: false,
166 saveUninitialized: true,
167 cookie: { secure: true }
168}))
169```
170
171For using secure cookies in production, but allowing for testing in development,
172the following is an example of enabling this setup based on `NODE_ENV` in express:
173
174```js
175var app = express()
176var sess = {
177 secret: 'keyboard cat',
178 cookie: {}
179}
180
181if (app.get('env') === 'production') {
182 app.set('trust proxy', 1) // trust first proxy
183 sess.cookie.secure = true // serve secure cookies
184}
185
186app.use(session(sess))
187```
188
189The `cookie.secure` option can also be set to the special value `'auto'` to have
190this setting automatically match the determined security of the connection. Be
191careful when using this setting if the site is available both as HTTP and HTTPS,
192as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
193is useful when the Express `"trust proxy"` setting is properly setup to simplify
194development vs production configuration.
195
196##### genid
197
198Function to call to generate a new session ID. Provide a function that returns
199a string that will be used as a session ID. The function is given `req` as the
200first argument if you want to use some value attached to `req` when generating
201the ID.
202
203The default value is a function which uses the `uid-safe` library to generate IDs.
204
205**NOTE** be careful to generate unique IDs so your sessions do not conflict.
206
207```js
208app.use(session({
209 genid: function(req) {
210 return genuuid() // use UUIDs for session IDs
211 },
212 secret: 'keyboard cat'
213}))
214```
215
216##### name
217
218The name of the session ID cookie to set in the response (and read from in the
219request).
220
221The default value is `'connect.sid'`.
222
223**Note** if you have multiple apps running on the same hostname (this is just
224the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
225name a different hostname), then you need to separate the session cookies from
226each other. The simplest method is to simply set different `name`s per app.
227
228##### proxy
229
230Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
231header).
232
233The default value is `undefined`.
234
235 - `true` The "X-Forwarded-Proto" header will be used.
236 - `false` All headers are ignored and the connection is considered secure only
237 if there is a direct TLS/SSL connection.
238 - `undefined` Uses the "trust proxy" setting from express
239
240##### resave
241
242Forces the session to be saved back to the session store, even if the session
243was never modified during the request. Depending on your store this may be
244necessary, but it can also create race conditions where a client makes two
245parallel requests to your server and changes made to the session in one
246request may get overwritten when the other request ends, even if it made no
247changes (this behavior also depends on what store you're using).
248
249The default value is `true`, but using the default has been deprecated,
250as the default will change in the future. Please research into this setting
251and choose what is appropriate to your use-case. Typically, you'll want
252`false`.
253
254How do I know if this is necessary for my store? The best way to know is to
255check with your store if it implements the `touch` method. If it does, then
256you can safely set `resave: false`. If it does not implement the `touch`
257method and your store sets an expiration date on stored sessions, then you
258likely need `resave: true`.
259
260##### rolling
261
262Force the session identifier cookie to be set on every response. The expiration
263is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
264countdown.
265
266The default value is `false`.
267
268With this enabled, the session identifier cookie will expire in
269[`maxAge`](#cookiemaxage) since the last response was sent instead of in
270[`maxAge`](#cookiemaxage) since the session was last modified by the server.
271
272This is typically used in conjuction with short, non-session-length
273[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
274with reduced potential of it occurring during on going server interactions.
275
276**Note** When this option is set to `true` but the `saveUninitialized` option is
277set to `false`, the cookie will not be set on a response with an uninitialized
278session. This option only modifies the behavior when an existing session was
279loaded for the request.
280
281##### saveUninitialized
282
283Forces a session that is "uninitialized" to be saved to the store. A session is
284uninitialized when it is new but not modified. Choosing `false` is useful for
285implementing login sessions, reducing server storage usage, or complying with
286laws that require permission before setting a cookie. Choosing `false` will also
287help with race conditions where a client makes multiple parallel requests
288without a session.
289
290The default value is `true`, but using the default has been deprecated, as the
291default will change in the future. Please research into this setting and
292choose what is appropriate to your use-case.
293
294**Note** if you are using Session in conjunction with PassportJS, Passport
295will add an empty Passport object to the session for use after a user is
296authenticated, which will be treated as a modification to the session, causing
297it to be saved. *This has been fixed in PassportJS 0.3.0*
298
299##### secret
300
301**Required option**
302
303This is the secret used to sign the session ID cookie. The secret can be any type
304of value that is supported by Node.js `crypto.createHmac` (like a string or a
305`Buffer`). This can be either a single secret, or an array of multiple secrets. If
306an array of secrets is provided, only the first element will be used to sign the
307session ID cookie, while all the elements will be considered when verifying the
308signature in requests. The secret itself should be not easily parsed by a human and
309would best be a random set of characters. A best practice may include:
310
311 - The use of environment variables to store the secret, ensuring the secret itself
312 does not exist in your repository.
313 - Periodic updates of the secret, while ensuring the previous secret is in the
314 array.
315
316Using a secret that cannot be guessed will reduce the ability to hijack a session to
317only guessing the session ID (as determined by the `genid` option).
318
319Changing the secret value will invalidate all existing sessions. In order to rotate
320the secret without invalidating sessions, provide an array of secrets, with the new
321secret as first element of the array, and including previous secrets as the later
322elements.
323
324**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
325contain at least 32 bytes of entropy.
326
327##### store
328
329The session store instance, defaults to a new `MemoryStore` instance.
330
331##### unset
332
333Control the result of unsetting `req.session` (through `delete`, setting to `null`,
334etc.).
335
336The default value is `'keep'`.
337
338 - `'destroy'` The session will be destroyed (deleted) when the response ends.
339 - `'keep'` The session in the store will be kept, but modifications made during
340 the request are ignored and not saved.
341
342### req.session
343
344To store or access session data, simply use the request property `req.session`,
345which is (generally) serialized as JSON by the store, so nested objects
346are typically fine. For example below is a user-specific view counter:
347
348```js
349// Use the session middleware
350app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
351
352// Access the session as req.session
353app.get('/', function(req, res, next) {
354 if (req.session.views) {
355 req.session.views++
356 res.setHeader('Content-Type', 'text/html')
357 res.write('<p>views: ' + req.session.views + '</p>')
358 res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
359 res.end()
360 } else {
361 req.session.views = 1
362 res.end('welcome to the session demo. refresh!')
363 }
364})
365```
366
367#### Session.regenerate(callback)
368
369To regenerate the session simply invoke the method. Once complete,
370a new SID and `Session` instance will be initialized at `req.session`
371and the `callback` will be invoked.
372
373```js
374req.session.regenerate(function(err) {
375 // will have a new session here
376})
377```
378
379#### Session.destroy(callback)
380
381Destroys the session and will unset the `req.session` property.
382Once complete, the `callback` will be invoked.
383
384```js
385req.session.destroy(function(err) {
386 // cannot access session here
387})
388```
389
390#### Session.reload(callback)
391
392Reloads the session data from the store and re-populates the
393`req.session` object. Once complete, the `callback` will be invoked.
394
395```js
396req.session.reload(function(err) {
397 // session updated
398})
399```
400
401#### Session.save(callback)
402
403Save the session back to the store, replacing the contents on the store with the
404contents in memory (though a store may do something else--consult the store's
405documentation for exact behavior).
406
407This method is automatically called at the end of the HTTP response if the
408session data has been altered (though this behavior can be altered with various
409options in the middleware constructor). Because of this, typically this method
410does not need to be called.
411
412There are some cases where it is useful to call this method, for example,
413redirects, long-lived requests or in WebSockets.
414
415```js
416req.session.save(function(err) {
417 // session saved
418})
419```
420
421#### Session.touch()
422
423Updates the `.maxAge` property. Typically this is
424not necessary to call, as the session middleware does this for you.
425
426### req.session.id
427
428Each session has a unique ID associated with it. This property is an
429alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
430It has been added to make the session ID accessible from the `session`
431object.
432
433### req.session.cookie
434
435Each session has a unique cookie object accompany it. This allows
436you to alter the session cookie per visitor. For example we can
437set `req.session.cookie.expires` to `false` to enable the cookie
438to remain for only the duration of the user-agent.
439
440#### Cookie.maxAge
441
442Alternatively `req.session.cookie.maxAge` will return the time
443remaining in milliseconds, which we may also re-assign a new value
444to adjust the `.expires` property appropriately. The following
445are essentially equivalent
446
447```js
448var hour = 3600000
449req.session.cookie.expires = new Date(Date.now() + hour)
450req.session.cookie.maxAge = hour
451```
452
453For example when `maxAge` is set to `60000` (one minute), and 30 seconds
454has elapsed it will return `30000` until the current request has completed,
455at which time `req.session.touch()` is called to reset
456`req.session.cookie.maxAge` to its original value.
457
458```js
459req.session.cookie.maxAge // => 30000
460```
461
462#### Cookie.originalMaxAge
463
464The `req.session.cookie.originalMaxAge` property returns the original
465`maxAge` (time-to-live), in milliseconds, of the session cookie.
466
467### req.sessionID
468
469To get the ID of the loaded session, access the request property
470`req.sessionID`. This is simply a read-only value set when a session
471is loaded/created.
472
473## Session Store Implementation
474
475Every session store _must_ be an `EventEmitter` and implement specific
476methods. The following methods are the list of **required**, **recommended**,
477and **optional**.
478
479 * Required methods are ones that this module will always call on the store.
480 * Recommended methods are ones that this module will call on the store if
481 available.
482 * Optional methods are ones this module does not call at all, but helps
483 present uniform stores to users.
484
485For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
486
487### store.all(callback)
488
489**Optional**
490
491This optional method is used to get all sessions in the store as an array. The
492`callback` should be called as `callback(error, sessions)`.
493
494### store.destroy(sid, callback)
495
496**Required**
497
498This required method is used to destroy/delete a session from the store given
499a session ID (`sid`). The `callback` should be called as `callback(error)` once
500the session is destroyed.
501
502### store.clear(callback)
503
504**Optional**
505
506This optional method is used to delete all sessions from the store. The
507`callback` should be called as `callback(error)` once the store is cleared.
508
509### store.length(callback)
510
511**Optional**
512
513This optional method is used to get the count of all sessions in the store.
514The `callback` should be called as `callback(error, len)`.
515
516### store.get(sid, callback)
517
518**Required**
519
520This required method is used to get a session from the store given a session
521ID (`sid`). The `callback` should be called as `callback(error, session)`.
522
523The `session` argument should be a session if found, otherwise `null` or
524`undefined` if the session was not found (and there was no error). A special
525case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
526
527### store.set(sid, session, callback)
528
529**Required**
530
531This required method is used to upsert a session into the store given a
532session ID (`sid`) and session (`session`) object. The callback should be
533called as `callback(error)` once the session has been set in the store.
534
535### store.touch(sid, session, callback)
536
537**Recommended**
538
539This recommended method is used to "touch" a given session given a
540session ID (`sid`) and session (`session`) object. The `callback` should be
541called as `callback(error)` once the session has been touched.
542
543This is primarily used when the store will automatically delete idle sessions
544and this method is used to signal to the store the given session is active,
545potentially resetting the idle timer.
546
547## Compatible Session Stores
548
549The following modules implement a session store that is compatible with this
550module. Please make a PR to add additional modules :)
551
552[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
553
554[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
555[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
556
557[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
558
559[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
560[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
561
562[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
563
564[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
565[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
566
567[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
568stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
569and other multi-core embedded devices).
570
571[cluster-store-url]: https://www.npmjs.com/package/cluster-store
572[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
573
574[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
575
576[connect-arango-url]: https://www.npmjs.com/package/connect-arango
577[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
578
579[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
580
581[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
582[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
583
584[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
585
586[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
587[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
588
589[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
590
591[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
592[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
593
594[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
595
596[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
597[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
598
599[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
600
601[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
602[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
603
604[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
605
606[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
607[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
608
609[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
610
611[connect-db2-url]: https://www.npmjs.com/package/connect-db2
612[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
613
614[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
615
616[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
617[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
618
619[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
620
621[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
622[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
623
624[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
625
626[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
627[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
628
629[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
630
631[connect-loki-url]: https://www.npmjs.com/package/connect-loki
632[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
633
634[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
635
636[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
637[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
638
639[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
640
641[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
642[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
643
644[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
645[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
646
647[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
648[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
649
650[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
651
652[connect-ml-url]: https://www.npmjs.com/package/connect-ml
653[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
654
655[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
656
657[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
658[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
659
660[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
661
662[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
663[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
664
665[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
666
667[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
668[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
669
670[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
671
672[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
673[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
674
675[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
676
677[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
678[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
679
680[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
681
682[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
683[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
684
685[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
686
687[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
688[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
689
690[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
691
692[connect-redis-url]: https://www.npmjs.com/package/connect-redis
693[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
694
695[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
696
697[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
698[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
699
700[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
701[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
702
703[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
704[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
705
706[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
707[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
708
709[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
710[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
711
712[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
713
714[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
715[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
716
717[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
718
719[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
720[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
721
722[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
723
724[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
725[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
726
727[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
728
729[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
730[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
731
732[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
733
734[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
735[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
736
737[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
738
739[express-etcd-url]: https://www.npmjs.com/package/express-etcd
740[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
741
742[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
743[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
744
745[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
746[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
747
748[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
749
750[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
751[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
752
753[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
754[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
755
756[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
757[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
758
759[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
760A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
761a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
762
763[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
764[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
765
766[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
767
768[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
769[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
770
771[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
772
773[express-session-level-url]: https://www.npmjs.com/package/express-session-level
774[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
775
776[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerfull, flat file database.
777
778[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
779[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
780
781[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
782
783[express-sessions-url]: https://www.npmjs.com/package/express-sessions
784[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
785
786[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
787
788[firestore-store-url]: https://www.npmjs.com/package/firestore-store
789[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
790
791[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
792based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
793
794[fortune-session-url]: https://www.npmjs.com/package/fortune-session
795[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
796
797[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
798
799[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
800[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
801
802[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
803
804[level-session-store-url]: https://www.npmjs.com/package/level-session-store
805[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
806
807[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
808
809[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
810[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
811
812[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
813
814[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
815[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
816
817[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
818
819[memorystore-url]: https://www.npmjs.com/package/memorystore
820[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
821
822[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
823
824[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
825[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
826
827[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
828
829[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
830[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
831
832[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
833
834[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
835[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
836
837[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
838
839[restsession-url]: https://www.npmjs.com/package/restsession
840[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
841
842[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
843
844[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
845[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
846
847[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
848
849[session-file-store-url]: https://www.npmjs.com/package/session-file-store
850[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
851
852[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
853
854[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
855[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
856
857[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
858
859[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
860[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
861
862[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
863
864[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
865[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
866
867[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
868
869[sessionstore-url]: https://www.npmjs.com/package/sessionstore
870[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
871
872[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
873
874[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
875[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
876
877## Examples
878
879### View counter
880
881A simple example using `express-session` to store page views for a user.
882
883```js
884var express = require('express')
885var parseurl = require('parseurl')
886var session = require('express-session')
887
888var app = express()
889
890app.use(session({
891 secret: 'keyboard cat',
892 resave: false,
893 saveUninitialized: true
894}))
895
896app.use(function (req, res, next) {
897 if (!req.session.views) {
898 req.session.views = {}
899 }
900
901 // get the url pathname
902 var pathname = parseurl(req).pathname
903
904 // count the views
905 req.session.views[pathname] = (req.session.views[pathname] || 0) + 1
906
907 next()
908})
909
910app.get('/foo', function (req, res, next) {
911 res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
912})
913
914app.get('/bar', function (req, res, next) {
915 res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
916})
917
918app.listen(3000)
919```
920
921### User login
922
923A simple example using `express-session` to keep a user log in session.
924
925```js
926var escapeHtml = require('escape-html')
927var express = require('express')
928var session = require('express-session')
929
930var app = express()
931
932app.use(session({
933 secret: 'keyboard cat',
934 resave: false,
935 saveUninitialized: true
936}))
937
938// middleware to test if authenticated
939function isAuthenticated (req, res, next) {
940 if (req.session.user) next()
941 else next('route')
942}
943
944app.get('/', isAuthenticated, function (req, res) {
945 // this is only called when there is an authentication user due to isAuthenticated
946 res.send('hello, ' + escapeHtml(req.session.user) + '!' +
947 ' <a href="/logout">Logout</a>')
948})
949
950app.get('/', function (req, res) {
951 res.send('<form action="/login" method="post">' +
952 'Username: <input name="user"><br>' +
953 'Password: <input name="pass" type="password"><br>' +
954 '<input type="submit" text="Login"></form>')
955})
956
957app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
958 // login logic to validate req.body.user and req.body.pass
959 // would be implemented here. for this example any combo works
960
961 // regenerate the session, which is good practice to help
962 // guard against forms of session fixation
963 req.session.regenerate(function (err) {
964 if (err) next(err)
965
966 // store user information in session, typically a user id
967 req.session.user = req.body.user
968
969 // save the session before redirection to ensure page
970 // load does not happen before session is saved
971 req.session.save(function (err) {
972 if (err) return next(err)
973 res.redirect('/')
974 })
975 })
976})
977
978app.get('/logout', function (req, res, next) {
979 // logout logic
980
981 // clear the user from the session object and save.
982 // this will ensure that re-using the old session id
983 // does not have a logged in user
984 req.session.user = null
985 req.session.save(function (err) {
986 if (err) next(err)
987
988 // regenerate the session, which is good practice to help
989 // guard against forms of session fixation
990 req.session.regenerate(function (err) {
991 if (err) next(err)
992 res.redirect('/')
993 })
994 })
995})
996
997app.listen(3000)
998```
999
1000## Debugging
1001
1002This module uses the [debug](https://www.npmjs.com/package/debug) module
1003internally to log information about session operations.
1004
1005To see all the internal logs, set the `DEBUG` environment variable to
1006`express-session` when launching your app (`npm start`, in this example):
1007
1008```sh
1009$ DEBUG=express-session npm start
1010```
1011
1012On Windows, use the corresponding command;
1013
1014```sh
1015> set DEBUG=express-session & npm start
1016```
1017
1018## License
1019
1020[MIT](LICENSE)
1021
1022[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
1023[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
1024[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
1025[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
1026[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
1027[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
1028[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
1029[node-url]: https://nodejs.org/en/download
1030[npm-downloads-image]: https://badgen.net/npm/dm/express-session
1031[npm-url]: https://npmjs.org/package/express-session
1032[npm-version-image]: https://badgen.net/npm/v/express-session