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 |
|
10 | This 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
|
21 | var session = require('express-session')
|
22 | ```
|
23 |
|
24 | ### session(options)
|
25 |
|
26 | Create a session middleware with the given `options`.
|
27 |
|
28 | **Note** Session data is _not_ saved in the cookie itself, just the session ID.
|
29 | Session data is stored server-side.
|
30 |
|
31 | **Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
|
32 | no longer needs to be used for this module to work. This module now directly reads
|
33 | and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
|
34 | if the `secret` is not the same between this module and `cookie-parser`.
|
35 |
|
36 | **Warning** The default server-side session storage, `MemoryStore`, is _purposely_
|
37 | not designed for a production environment. It will leak memory under most
|
38 | conditions, does not scale past a single process, and is meant for debugging and
|
39 | developing.
|
40 |
|
41 | For 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 |
|
49 | Settings object for the session ID cookie. The default value is
|
50 | `{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
|
51 |
|
52 | The following are options that can be set in this object.
|
53 |
|
54 | ##### cookie.domain
|
55 |
|
56 | Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
|
57 | is set, and most clients will consider the cookie to apply to only the current
|
58 | domain.
|
59 |
|
60 | ##### cookie.expires
|
61 |
|
62 | Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
|
63 | By 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
|
65 | application.
|
66 |
|
67 | **Note** If both `expires` and `maxAge` are set in the options, then the last one
|
68 | defined in the object is what is used.
|
69 |
|
70 | **Note** The `expires` option should not be set directly; instead only use the `maxAge`
|
71 | option.
|
72 |
|
73 | ##### cookie.httpOnly
|
74 |
|
75 | Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
|
76 | the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
|
77 | attribute is set.
|
78 |
|
79 | **Note** be careful when setting this to `true`, as compliant clients will not allow
|
80 | client-side JavaScript to see the cookie in `document.cookie`.
|
81 |
|
82 | ##### cookie.maxAge
|
83 |
|
84 | Specifies 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,
|
87 | no maximum age is set.
|
88 |
|
89 | **Note** If both `expires` and `maxAge` are set in the options, then the last one
|
90 | defined in the object is what is used.
|
91 |
|
92 | ##### cookie.partitioned
|
93 |
|
94 | Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
|
95 | attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
|
96 | By default, the `Partitioned` attribute is not set.
|
97 |
|
98 | **Note** This is an attribute that has not yet been fully standardized, and may
|
99 | change in the future. This also means many clients may ignore this attribute until
|
100 | they understand it.
|
101 |
|
102 | More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
|
103 |
|
104 | ##### cookie.path
|
105 |
|
106 | Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
|
107 | is the root path of the domain.
|
108 |
|
109 | ##### cookie.priority
|
110 |
|
111 | Specifies 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 |
|
117 | More 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.
|
121 | This also means many clients may ignore this attribute until they understand it.
|
122 |
|
123 | ##### cookie.sameSite
|
124 |
|
125 | Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
|
126 | By 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 |
|
134 | More 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
|
138 | the 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)
|
141 | that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
|
142 | set to `'none'`. Some web browsers or other clients may be adopting this specification.
|
143 |
|
144 | ##### cookie.secure
|
145 |
|
146 | Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
|
147 | the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
|
148 | attribute is not set.
|
149 |
|
150 | **Note** be careful when setting this to `true`, as compliant clients will not send
|
151 | the cookie back to the server in the future if the browser does not have an HTTPS
|
152 | connection.
|
153 |
|
154 | Please note that `secure: true` is a **recommended** option. However, it requires
|
155 | an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
|
156 | is set, and you access your site over HTTP, the cookie will not be set. If you
|
157 | have your node.js behind a proxy and are using `secure: true`, you need to set
|
158 | "trust proxy" in express:
|
159 |
|
160 | ```js
|
161 | var app = express()
|
162 | app.set('trust proxy', 1) // trust first proxy
|
163 | app.use(session({
|
164 | secret: 'keyboard cat',
|
165 | resave: false,
|
166 | saveUninitialized: true,
|
167 | cookie: { secure: true }
|
168 | }))
|
169 | ```
|
170 |
|
171 | For using secure cookies in production, but allowing for testing in development,
|
172 | the following is an example of enabling this setup based on `NODE_ENV` in express:
|
173 |
|
174 | ```js
|
175 | var app = express()
|
176 | var sess = {
|
177 | secret: 'keyboard cat',
|
178 | cookie: {}
|
179 | }
|
180 |
|
181 | if (app.get('env') === 'production') {
|
182 | app.set('trust proxy', 1) // trust first proxy
|
183 | sess.cookie.secure = true // serve secure cookies
|
184 | }
|
185 |
|
186 | app.use(session(sess))
|
187 | ```
|
188 |
|
189 | The `cookie.secure` option can also be set to the special value `'auto'` to have
|
190 | this setting automatically match the determined security of the connection. Be
|
191 | careful when using this setting if the site is available both as HTTP and HTTPS,
|
192 | as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
|
193 | is useful when the Express `"trust proxy"` setting is properly setup to simplify
|
194 | development vs production configuration.
|
195 |
|
196 | ##### genid
|
197 |
|
198 | Function to call to generate a new session ID. Provide a function that returns
|
199 | a string that will be used as a session ID. The function is given `req` as the
|
200 | first argument if you want to use some value attached to `req` when generating
|
201 | the ID.
|
202 |
|
203 | The 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
|
208 | app.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 |
|
218 | The name of the session ID cookie to set in the response (and read from in the
|
219 | request).
|
220 |
|
221 | The default value is `'connect.sid'`.
|
222 |
|
223 | **Note** if you have multiple apps running on the same hostname (this is just
|
224 | the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
|
225 | name a different hostname), then you need to separate the session cookies from
|
226 | each other. The simplest method is to simply set different `name`s per app.
|
227 |
|
228 | ##### proxy
|
229 |
|
230 | Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
|
231 | header).
|
232 |
|
233 | The 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 |
|
242 | Forces the session to be saved back to the session store, even if the session
|
243 | was never modified during the request. Depending on your store this may be
|
244 | necessary, but it can also create race conditions where a client makes two
|
245 | parallel requests to your server and changes made to the session in one
|
246 | request may get overwritten when the other request ends, even if it made no
|
247 | changes (this behavior also depends on what store you're using).
|
248 |
|
249 | The default value is `true`, but using the default has been deprecated,
|
250 | as the default will change in the future. Please research into this setting
|
251 | and choose what is appropriate to your use-case. Typically, you'll want
|
252 | `false`.
|
253 |
|
254 | How do I know if this is necessary for my store? The best way to know is to
|
255 | check with your store if it implements the `touch` method. If it does, then
|
256 | you can safely set `resave: false`. If it does not implement the `touch`
|
257 | method and your store sets an expiration date on stored sessions, then you
|
258 | likely need `resave: true`.
|
259 |
|
260 | ##### rolling
|
261 |
|
262 | Force the session identifier cookie to be set on every response. The expiration
|
263 | is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
|
264 | countdown.
|
265 |
|
266 | The default value is `false`.
|
267 |
|
268 | With 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 |
|
272 | This is typically used in conjuction with short, non-session-length
|
273 | [`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
|
274 | with 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
|
277 | set to `false`, the cookie will not be set on a response with an uninitialized
|
278 | session. This option only modifies the behavior when an existing session was
|
279 | loaded for the request.
|
280 |
|
281 | ##### saveUninitialized
|
282 |
|
283 | Forces a session that is "uninitialized" to be saved to the store. A session is
|
284 | uninitialized when it is new but not modified. Choosing `false` is useful for
|
285 | implementing login sessions, reducing server storage usage, or complying with
|
286 | laws that require permission before setting a cookie. Choosing `false` will also
|
287 | help with race conditions where a client makes multiple parallel requests
|
288 | without a session.
|
289 |
|
290 | The default value is `true`, but using the default has been deprecated, as the
|
291 | default will change in the future. Please research into this setting and
|
292 | choose what is appropriate to your use-case.
|
293 |
|
294 | **Note** if you are using Session in conjunction with PassportJS, Passport
|
295 | will add an empty Passport object to the session for use after a user is
|
296 | authenticated, which will be treated as a modification to the session, causing
|
297 | it to be saved. *This has been fixed in PassportJS 0.3.0*
|
298 |
|
299 | ##### secret
|
300 |
|
301 | **Required option**
|
302 |
|
303 | This is the secret used to sign the session ID cookie. The secret can be any type
|
304 | of 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
|
306 | an array of secrets is provided, only the first element will be used to sign the
|
307 | session ID cookie, while all the elements will be considered when verifying the
|
308 | signature in requests. The secret itself should be not easily parsed by a human and
|
309 | would 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 |
|
316 | Using a secret that cannot be guessed will reduce the ability to hijack a session to
|
317 | only guessing the session ID (as determined by the `genid` option).
|
318 |
|
319 | Changing the secret value will invalidate all existing sessions. In order to rotate
|
320 | the secret without invalidating sessions, provide an array of secrets, with the new
|
321 | secret as first element of the array, and including previous secrets as the later
|
322 | elements.
|
323 |
|
324 | **Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
|
325 | contain at least 32 bytes of entropy.
|
326 |
|
327 | ##### store
|
328 |
|
329 | The session store instance, defaults to a new `MemoryStore` instance.
|
330 |
|
331 | ##### unset
|
332 |
|
333 | Control the result of unsetting `req.session` (through `delete`, setting to `null`,
|
334 | etc.).
|
335 |
|
336 | The 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 |
|
344 | To store or access session data, simply use the request property `req.session`,
|
345 | which is (generally) serialized as JSON by the store, so nested objects
|
346 | are typically fine. For example below is a user-specific view counter:
|
347 |
|
348 | ```js
|
349 | // Use the session middleware
|
350 | app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
|
351 |
|
352 | // Access the session as req.session
|
353 | app.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 |
|
369 | To regenerate the session simply invoke the method. Once complete,
|
370 | a new SID and `Session` instance will be initialized at `req.session`
|
371 | and the `callback` will be invoked.
|
372 |
|
373 | ```js
|
374 | req.session.regenerate(function(err) {
|
375 | // will have a new session here
|
376 | })
|
377 | ```
|
378 |
|
379 | #### Session.destroy(callback)
|
380 |
|
381 | Destroys the session and will unset the `req.session` property.
|
382 | Once complete, the `callback` will be invoked.
|
383 |
|
384 | ```js
|
385 | req.session.destroy(function(err) {
|
386 | // cannot access session here
|
387 | })
|
388 | ```
|
389 |
|
390 | #### Session.reload(callback)
|
391 |
|
392 | Reloads the session data from the store and re-populates the
|
393 | `req.session` object. Once complete, the `callback` will be invoked.
|
394 |
|
395 | ```js
|
396 | req.session.reload(function(err) {
|
397 | // session updated
|
398 | })
|
399 | ```
|
400 |
|
401 | #### Session.save(callback)
|
402 |
|
403 | Save the session back to the store, replacing the contents on the store with the
|
404 | contents in memory (though a store may do something else--consult the store's
|
405 | documentation for exact behavior).
|
406 |
|
407 | This method is automatically called at the end of the HTTP response if the
|
408 | session data has been altered (though this behavior can be altered with various
|
409 | options in the middleware constructor). Because of this, typically this method
|
410 | does not need to be called.
|
411 |
|
412 | There are some cases where it is useful to call this method, for example,
|
413 | redirects, long-lived requests or in WebSockets.
|
414 |
|
415 | ```js
|
416 | req.session.save(function(err) {
|
417 | // session saved
|
418 | })
|
419 | ```
|
420 |
|
421 | #### Session.touch()
|
422 |
|
423 | Updates the `.maxAge` property. Typically this is
|
424 | not necessary to call, as the session middleware does this for you.
|
425 |
|
426 | ### req.session.id
|
427 |
|
428 | Each session has a unique ID associated with it. This property is an
|
429 | alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
|
430 | It has been added to make the session ID accessible from the `session`
|
431 | object.
|
432 |
|
433 | ### req.session.cookie
|
434 |
|
435 | Each session has a unique cookie object accompany it. This allows
|
436 | you to alter the session cookie per visitor. For example we can
|
437 | set `req.session.cookie.expires` to `false` to enable the cookie
|
438 | to remain for only the duration of the user-agent.
|
439 |
|
440 | #### Cookie.maxAge
|
441 |
|
442 | Alternatively `req.session.cookie.maxAge` will return the time
|
443 | remaining in milliseconds, which we may also re-assign a new value
|
444 | to adjust the `.expires` property appropriately. The following
|
445 | are essentially equivalent
|
446 |
|
447 | ```js
|
448 | var hour = 3600000
|
449 | req.session.cookie.expires = new Date(Date.now() + hour)
|
450 | req.session.cookie.maxAge = hour
|
451 | ```
|
452 |
|
453 | For example when `maxAge` is set to `60000` (one minute), and 30 seconds
|
454 | has elapsed it will return `30000` until the current request has completed,
|
455 | at which time `req.session.touch()` is called to reset
|
456 | `req.session.cookie.maxAge` to its original value.
|
457 |
|
458 | ```js
|
459 | req.session.cookie.maxAge // => 30000
|
460 | ```
|
461 |
|
462 | #### Cookie.originalMaxAge
|
463 |
|
464 | The `req.session.cookie.originalMaxAge` property returns the original
|
465 | `maxAge` (time-to-live), in milliseconds, of the session cookie.
|
466 |
|
467 | ### req.sessionID
|
468 |
|
469 | To 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
|
471 | is loaded/created.
|
472 |
|
473 | ## Session Store Implementation
|
474 |
|
475 | Every session store _must_ be an `EventEmitter` and implement specific
|
476 | methods. The following methods are the list of **required**, **recommended**,
|
477 | and **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 |
|
485 | For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
|
486 |
|
487 | ### store.all(callback)
|
488 |
|
489 | **Optional**
|
490 |
|
491 | This 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 |
|
498 | This required method is used to destroy/delete a session from the store given
|
499 | a session ID (`sid`). The `callback` should be called as `callback(error)` once
|
500 | the session is destroyed.
|
501 |
|
502 | ### store.clear(callback)
|
503 |
|
504 | **Optional**
|
505 |
|
506 | This 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 |
|
513 | This optional method is used to get the count of all sessions in the store.
|
514 | The `callback` should be called as `callback(error, len)`.
|
515 |
|
516 | ### store.get(sid, callback)
|
517 |
|
518 | **Required**
|
519 |
|
520 | This required method is used to get a session from the store given a session
|
521 | ID (`sid`). The `callback` should be called as `callback(error, session)`.
|
522 |
|
523 | The `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
|
525 | case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
|
526 |
|
527 | ### store.set(sid, session, callback)
|
528 |
|
529 | **Required**
|
530 |
|
531 | This required method is used to upsert a session into the store given a
|
532 | session ID (`sid`) and session (`session`) object. The callback should be
|
533 | called as `callback(error)` once the session has been set in the store.
|
534 |
|
535 | ### store.touch(sid, session, callback)
|
536 |
|
537 | **Recommended**
|
538 |
|
539 | This recommended method is used to "touch" a given session given a
|
540 | session ID (`sid`) and session (`session`) object. The `callback` should be
|
541 | called as `callback(error)` once the session has been touched.
|
542 |
|
543 | This is primarily used when the store will automatically delete idle sessions
|
544 | and this method is used to signal to the store the given session is active,
|
545 | potentially resetting the idle timer.
|
546 |
|
547 | ## Compatible Session Stores
|
548 |
|
549 | The following modules implement a session store that is compatible with this
|
550 | module. 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
|
568 | stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
|
569 | and 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]
|
760 | A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
|
761 | a [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)
|
792 | based 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 |
|
881 | A simple example using `express-session` to store page views for a user.
|
882 |
|
883 | ```js
|
884 | var express = require('express')
|
885 | var parseurl = require('parseurl')
|
886 | var session = require('express-session')
|
887 |
|
888 | var app = express()
|
889 |
|
890 | app.use(session({
|
891 | secret: 'keyboard cat',
|
892 | resave: false,
|
893 | saveUninitialized: true
|
894 | }))
|
895 |
|
896 | app.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 |
|
910 | app.get('/foo', function (req, res, next) {
|
911 | res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
|
912 | })
|
913 |
|
914 | app.get('/bar', function (req, res, next) {
|
915 | res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
|
916 | })
|
917 |
|
918 | app.listen(3000)
|
919 | ```
|
920 |
|
921 | ### User login
|
922 |
|
923 | A simple example using `express-session` to keep a user log in session.
|
924 |
|
925 | ```js
|
926 | var escapeHtml = require('escape-html')
|
927 | var express = require('express')
|
928 | var session = require('express-session')
|
929 |
|
930 | var app = express()
|
931 |
|
932 | app.use(session({
|
933 | secret: 'keyboard cat',
|
934 | resave: false,
|
935 | saveUninitialized: true
|
936 | }))
|
937 |
|
938 | // middleware to test if authenticated
|
939 | function isAuthenticated (req, res, next) {
|
940 | if (req.session.user) next()
|
941 | else next('route')
|
942 | }
|
943 |
|
944 | app.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 |
|
950 | app.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 |
|
957 | app.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 |
|
978 | app.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 |
|
997 | app.listen(3000)
|
998 | ```
|
999 |
|
1000 | ## Debugging
|
1001 |
|
1002 | This module uses the [debug](https://www.npmjs.com/package/debug) module
|
1003 | internally to log information about session operations.
|
1004 |
|
1005 | To 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 |
|
1012 | On 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
|