{"id":14969177,"url":"https://github.com/fastify/session","last_synced_at":"2025-05-15T11:06:34.436Z","repository":{"id":36976495,"uuid":"390671376","full_name":"fastify/session","owner":"fastify","description":"Session plugin for fastify","archived":false,"fork":false,"pushed_at":"2025-05-01T04:13:46.000Z","size":492,"stargazers_count":116,"open_issues_count":14,"forks_count":51,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-05-01T05:20:08.519Z","etag":null,"topics":["fastify","fastify-plugin"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@fastify/session","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fastify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"fastify","open_collective":"fastify"}},"created_at":"2021-07-29T09:29:49.000Z","updated_at":"2025-05-01T04:12:43.000Z","dependencies_parsed_at":"2023-12-08T10:29:49.702Z","dependency_job_id":"dcb6272a-a0d9-4c74-96bc-07d5f1386262","html_url":"https://github.com/fastify/session","commit_stats":{"total_commits":400,"total_committers":67,"mean_commits":5.970149253731344,"dds":0.7,"last_synced_commit":"da1ad38bd085b4cb13e118645394c3b767eec2b0"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fsession","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fsession/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fsession/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fsession/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fastify","download_url":"https://codeload.github.com/fastify/session/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254328385,"owners_count":22052632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastify","fastify-plugin"],"created_at":"2024-09-24T13:41:17.636Z","updated_at":"2025-05-15T11:06:34.411Z","avatar_url":"https://github.com/fastify.png","language":"JavaScript","readme":"# @fastify/session\n\n[![CI](https://github.com/fastify/session/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/session/actions/workflows/ci.yml)\n[![NPM version](https://img.shields.io/npm/v/@fastify/session.svg?style=flat)](https://www.npmjs.com/package/@fastify/session)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)\n\nA session plugin for [fastify](http://fastify.dev/).\nRequires the [@fastify/cookie](https://github.com/fastify/fastify-cookie) plugin.\n\n**NOTE:** This is the continuation of [fastify-session](https://github.com/SerayaEryn/fastify-session) which is unmaintained by now. All work credit till [`e201f7`](https://github.com/fastify/session/commit/e201f78fc9d7bd33c6f2e84988be7c8af4b5a8a3) commit goes to [SerayaEryn](https://github.com/SerayaEryn) and contributors.\n\n## Install\n\n```\nnpm i @fastify/session\n```\n\n## Usage\n\n```js\nconst fastify = require('fastify');\nconst fastifySession = require('@fastify/session');\nconst fastifyCookie = require('@fastify/cookie');\n\nconst app = fastify();\napp.register(fastifyCookie);\napp.register(fastifySession, {secret: 'a secret with minimum length of 32 characters'});\n```\nStore data in the session by adding it to the `session` decorator at the `request`:\n```js\napp.register(fastifySession, {secret: 'a secret with minimum length of 32 characters'});\napp.addHook('preHandler', (request, reply, next) =\u003e {\n  request.session.user = {name: 'max'};\n  next();\n})\n```\n**NOTE**: For all unencrypted (HTTP) connections, you need to set the `secure` cookie option to `false`. See below for all cookie options and their details.\nThe `session` object has methods that allow you to get, save, reload, and delete sessions.\n```js\napp.register(fastifySession, {secret: 'a secret with minimum length of 32 characters'});\napp.addHook('preHandler', (request, reply, next) =\u003e {\n  request.session.destroy(next);\n})\n```\n\n## Examples\n\n* [Authentication](https://github.com/fastify/example/tree/main/fastify-session-authentication)\n\n## API\n### session(fastify, options, next)\nThe session plugin accepts the following options. It decorates the request with the `sessionStore` and a `session` object. The session data is stored server-side using the configured session store.\n#### options\n##### secret (required)\nThe secret used to sign the cookie. Must be an array of strings or a string with a length of 32 or greater or a custom signer.\n\nIf an array, the first secret is used to sign new cookies and is the first to be checked for incoming cookies.\nFurther secrets in the array are used to check incoming cookies in the order specified.\n\nFor a custom signer see the documentation of [@fastify/cookie](https://github.com/fastify/fastify-cookie#custom-cookie-signer)\n\nNote that the rest of the application may manipulate the array during its life cycle. This can be done by storing the array in a separate variable that is later used with mutating methods like unshift(), pop(), splice(), etc.\nThis can be used to rotate the signing secret at regular intervals. A secret should remain somewhere in the array as long as there are active sessions with cookies signed by it. Secrets management is left up to the rest of the application.\n##### cookieName (optional)\nThe name of the session cookie. Defaults to `sessionId`.\n##### cookiePrefix (optional)\nPrefix for the value of the cookie. This is useful for compatibility with `express-session`, which prefixes all cookies with `\"s:\"`. Defaults to `\"\"`.\n##### cookie\nThe options object is used to generate the `Set-Cookie` header of the session cookie. May have the following properties:\n* `path` - The `Path` attribute. Defaults to `/` (the root path).\n* `maxAge` - A `number` in milliseconds that specifies the `Expires` attribute by adding the specified milliseconds to the current date. If both `expires` and `maxAge` are set, then `maxAge` is used.\n* `httpOnly` - The `boolean` value of the `HttpOnly` attribute. Defaults to true.\n* `secure` - The `boolean` value of the `Secure` attribute. Set this option to false when communicating over an unencrypted (HTTP) connection. Value can be set to `auto`; in this case, the `Secure` attribute will be set to false for an HTTP request. In the case of HTTPS, it will be set to true.  Defaults to true.\n* `expires` - The expiration `date` used for the `Expires` attribute. If both `expires` and `maxAge` are set, then `maxAge` is used.\n* `sameSite`- The `boolean` or `string` of the `SameSite` attribute. Using `Secure` mode with `auto` attribute will change the behavior of the `SameSite` attribute in `http` mode. The `SameSite` attribute will automatically be set to `Lax` with an `http` request. See this [link](https://www.chromium.org/updates/same-site).\n* `domain` - The `Domain` attribute.\n* `partitioned` (**experimental**) - The `boolean` value of the `Partitioned` attribute. Using the Partitioned attribute as part of Cookies Having Independent Partitioned State (CHIPS) to allow cross-site access with a separate cookie used per site. Defaults to false.\n\n##### store\nA session store. Needs the following methods:\n* set(sessionId, session, callback)\n* get(sessionId, callback)\n* destroy(sessionId, callback)\n\nCompatible with stores from [express-session](https://github.com/expressjs/session).\n\nIf you are terminating HTTPs at\nthe reverse proxy, you need to add the `trustProxy` setting to your fastify instance if you want to use secure cookies.\n\nDefaults to a simple in-memory store.\u003c/br\u003e\n**Note**: The default store should not be used in a production environment because it will leak memory.\n\n##### saveUninitialized (optional)\nSave sessions to the store, even when they are new and not modified— defaults to `true`.\nSetting this to `false` can save storage space and comply with the EU cookie law.\n\n##### rolling (optional)\nForces the session identifier cookie to be set on every response. The expiration is reset to the original maxAge - effectively resetting the cookie lifetime. This is typically used in conjunction with short, non-session-length maxAge values to provide a quick expiration of the session data with reduced potential of session expiration occurring during ongoing server interactions. Defaults to true.\n\n##### idGenerator(request) (optional)\n\nFunction used to generate new session IDs.\nCustom implementation example:\n```js\nconst uid = require('uid-safe').sync\n\nidGenerator: (request) =\u003e {\n     if (request.session.returningVisitor) return `returningVisitor-${uid(24)}`\n     else return uid(24)\n}\n```\n\n#### request.session\n\nAllows to access or modify the session data.\n\n#### Session#destroy(callback)\n\nAllows to destroy the session in the store. If you do not pass a callback, a Promise will be returned.\n\n#### Session#touch()\n\nUpdates the `expires` property of the session's cookie.\n\n#### Session#options(opts)\n\nUpdates default options for setCookie inside a route.\n\n```js\nfastify.post('/', (request, reply) =\u003e {\n  request.session.set('data', request.body)\n  // .options takes any parameter that you can pass to setCookie\n  request.session.options({ maxAge: 60 * 60 }); // 3600 seconds =\u003e maxAge is always passed in seconds\n  reply.send('hello world')\n})\n```\n\n#### Session#regenerate([ignoreFields, ]callback)\n\nRegenerates the session by generating a new `sessionId` and persist it to the store. If you do not pass a callback, a Promise will be returned.\n```js\nfastify.get('/regenerate', (request, reply, done) =\u003e {\n  request.session.regenerate(error =\u003e {\n    if (error) {\n      done(error);\n      return;\n    }\n    reply.send(request.session.sessionId);\n  });\n});\n```\n\nYou can pass an array of fields that should be kept when the session is regenerated.\n\n#### Session#reload(callback)\n\nReloads the session data from the store and re-populates the `request.session` object. If you do not pass a callback, a Promise will be returned.\n\n#### Session#save(callback)\n\nSave the session back to the store, replacing the contents on the store with the contents in memory. If you do not pass a callback, a Promise will be returned.\n\n#### Session#get(key)\n\nGets a value from the session\n\n#### Session#set(key, value)\n\nSets a value in the session\n\n#### Session#isModified()\n\nWhether the session has been modified from what was loaded from the store (or created)\n\n#### Session#isSaved()\n\nWhether the session (and any of its potential modifications) has persisted in the store.\n\n### fastify.decryptSession(sessionId, request, cookieOptions, next)\nThis plugin also decorates the fastify instance with `decryptSession` in case you want to decrypt the session manually.\n\n```js\nconst { sessionId } = fastify.parseCookie(cookieHeader);\nconst request = {}\nfastify.decryptSession(sessionId, request, () =\u003e {\n  // request.session should be available here\n})\n\n// or decrypt with custom cookie options:\nfastify.decryptSession(sessionId, request, { maxAge: 86400 }, () =\u003e {\n  // ...\n})\n```\n\n### Typescript support:\nThis plugin supports typescript, and you can extend the fastify module to add your custom session type.\n\n```ts\n// Use module imports rather than commonjs' require for correct declaration merging in TypeScript.\n\n// Wrong ❌:\n// const fastifySession = require('@fastify/session');\n// const fastifyCookie = require('@fastify/cookie');\n\n// Correct ✔️:\nimport { fastifySession } from '@fastify/session';\nimport { fastifyCookie } from '@fastify/cookie';\n\n// Extend fastify.session with your custom type.\ndeclare module \"fastify\" {\n    interface Session {\n        user_id: string\n        other_key: your_prefer_type\n        id?: number\n    }\n}\n```\n\nWhen you think that the getter or setter is too strict.\nYou are allowed to use `any` types to loosen the check.\n\n```ts\nfastify.get('/', async function(request) {\n  request.session.get\u003cany\u003e('not-exist')\n  request.session.set\u003cany\u003e('not-exist', 'happy')\n})\n```\n\n## License\n\nLicensed under [MIT](./LICENSE).\n","funding_links":["https://github.com/sponsors/fastify","https://opencollective.com/fastify"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Fsession","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffastify%2Fsession","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Fsession/lists"}