Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add sessions usage #1445

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions docs/content/1.guide/7.sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: Sessions
icon: ri:arrow-left-right-line
---

# Sessions

Nitro, supports user sessions out of the box. (through [unjs/h3](https://github.com/h3))

::alert{type="info"}
A session is a series of interactions between a client and server. Because HTTP is a stateless protocol, sessions allow association of multiple requests to the same client using a cookie which is automatically sent by the browser to the server on each request.
::

## Session Utilities

You can use to manage sessions with available auto imported utils:

- `useSession(event, sessionConfig)`: Initializes a session and returns a wrapper to control it.
- `getSession(event, sessionConfig)`: Initializes or gets the current user session.
- `updateSession(event, sessionConfig)`: Updates data of the current session.
- `clearSession(event, sessionConfig)`: Clears the current session.

Advanced utils:

- `sealSession(event, sessionConfig)`: Encrypts the current user session.
- `unsealSession(event, sessionConfig, sealed)`: Decryptes the current user session.


## Use sessions

To use sessions, you've just to use the `useSession` composable and provide a strong password in one of your event handler. each time a client will hit this endpoint, the composable will first try to get the session from a header named `x-h3-session` then from a cookie named `h3`. If no session is found, a new one will be created.

```ts [routes/index.ts]
export default defineEventHandler(async (event) => {
const sessionConfig = useRuntimeConfig().session
const session = await useSession(event, {
name: sessionConfig.name,
password: sessionConfig.password
})

return
})
```

Then, you must update your `nitro.config.ts` with your session config:

```ts [nitro.config.ts]
export default defineNitroConfig({
runtimeConfig: {
session: {
name: "custom-name", // The name of the cookie and the header, x-<name>-session, used to retrieve the session
password: process.env.NITRO_SESSION_PASSWORD || "", // Password used to seal the session
}
}
})
```

We recommend you to use a global config from `nitro.config.ts` to easily retrieve session settings in your event handlers.

Starting from now, Nitro will return a header `Set-Cookie` with a cookie named `custom-name` to the client. This cookie is sealed so the client won't be able to read or modify it.

::alert{type="info"}
Using a custom name is useful when you want to use multiple sessions in the same application.
::

The `useSession` composable returns an object with three properties:

- `data`, the data of the current session
- `update`, a function to update the data of the current session
- `clear`, a function to clear the current session

So, you can easily update the data of the current session:

```ts [routes/index.ts]
export default defineEventHandler(async (event) => {
const sessionConfig = useRuntimeConfig().session
const session = await useSession(event, {
name: sessionConfig.name,
password: sessionConfig.password
})

session.update({ foo: 'bar' })

return session.data
})
```

Then, when the client will hit Nitro with the cookie, you will be able to retrieve the data of the session:

```ts [routes/data.ts]
export default defineEventHandler(async (event) => {
const sessionConfig = useRuntimeConfig().session
const session = await useSession(event, {
name: sessionConfig.name,
password: sessionConfig.password
})

return session.data // { foo: 'bar' }
})
```

::callout{type="info"}
#summary
How `useSession` works?
#content
Under the hood, the `useSession` composable will use the `getSession` to retrieve the current session returned as `data` and return the `updateSession` as `update` and `clearSession` as `clear`. `sealSession` is used when the `updateSession` is called with the provided password and the `unsealSession` is used when the `getSession` is called with the provided password.
::

## Customization

### Cookie

You can customize the cookie name by providing a `name` property in the options of `useSession`. You can also add serialized options to the cookie by providing a `cookie` property in the options of `useSession`. This property is an object with the following properties:

- `maxAge`, the maximum age of the cookie **in seconds**
- `expires`, the expiration date of the cookie
- `path`, the path of the cookie
- `domain`, the domain of the cookie
- `secure`, a boolean indicating if the cookie is secure
- `httpOnly`, a boolean indicating if the cookie is http only
- `sameSite`, the same site policy of the cookie

<!-- TODO: we could add more informations about the crypto and seal options but I dont' know if it's relevant here. -->