-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Sarah Rainsberger <[email protected]> Co-authored-by: Princesseuh <[email protected]> Co-authored-by: ascorbic <[email protected]> Co-authored-by: sarahrainsberger <[email protected]> Co-authored-by: delucis <[email protected]> Co-authored-by: Florian Lefebvre <[email protected]> Co-authored-by: oliverlynch <[email protected]> Co-authored-by: Matt Kane <[email protected]>
- Loading branch information
1 parent
763db6c
commit 2dcdf53
Showing
7 changed files
with
351 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/content/docs/en/reference/errors/session-storage-init-error.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
# NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' | ||
# Do not make edits to it directly, they will be overwritten. | ||
# Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts | ||
# Translators, please remove this note and the <DontEditWarning/> component. | ||
|
||
title: Session storage could not be initialized. | ||
i18nReady: true | ||
githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts | ||
--- | ||
import DontEditWarning from '~/components/DontEditWarning.astro' | ||
|
||
<DontEditWarning /> | ||
|
||
|
||
> **SessionStorageInitError**: Error when initializing session storageDRIVER ? ` WITH DRIVER ${DRIVER` : ''}. ERROR ?? '' | ||
## What went wrong? | ||
Thrown when the session storage could not be initialized. | ||
|
||
**See Also:** | ||
- [experimental.session](/en/reference/experimental-flags/sessions/) | ||
|
||
|
24 changes: 24 additions & 0 deletions
24
src/content/docs/en/reference/errors/session-storage-save-error.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
# NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' | ||
# Do not make edits to it directly, they will be overwritten. | ||
# Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts | ||
# Translators, please remove this note and the <DontEditWarning/> component. | ||
|
||
title: Session data could not be saved. | ||
i18nReady: true | ||
githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts | ||
--- | ||
import DontEditWarning from '~/components/DontEditWarning.astro' | ||
|
||
<DontEditWarning /> | ||
|
||
|
||
> **SessionStorageSaveError**: Error when saving session dataDRIVER ? ` WITH DRIVER ${DRIVER` : ''}. ERROR ?? '' | ||
## What went wrong? | ||
Thrown when the session data could not be saved. | ||
|
||
**See Also:** | ||
- [experimental.session](/en/reference/experimental-flags/sessions/) | ||
|
||
|
237 changes: 237 additions & 0 deletions
237
src/content/docs/en/reference/experimental-flags/sessions.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
--- | ||
title: Experimental sessions | ||
sidebar: | ||
label: Sessions | ||
i18nReady: true | ||
--- | ||
|
||
import Since from '~/components/Since.astro'; | ||
import ReadMore from '~/components/ReadMore.astro'; | ||
|
||
<p> | ||
|
||
**Type:** `SessionConfig`<br /> | ||
**Default:** `undefined`<br /> | ||
|
||
<Since v="5.1.0" /> | ||
</p> | ||
|
||
Sessions are used to store user state between requests for [on-demand rendered pages](/en/guides/on-demand-rendering/). | ||
|
||
This experimental feature allows you to store and access items such as login status, shopping cart contents, or other user-specific data: | ||
|
||
```astro title="src/components/CartButton.astro" {3} | ||
--- | ||
export const prerender = false; // Not needed in 'server' mode | ||
const cart = await Astro.session.get('cart'); | ||
--- | ||
<a href="/checkout">🛒 {cart?.length ?? 0} items</a> | ||
``` | ||
|
||
Sessions rely on a [configurable session `driver`](#enabling-experimental-sessions) to store data on the `session` object. A [session cookie](#cookies) stores an identifying session ID. | ||
|
||
The [`session` object](#sessions-api) allow you to interact with the stored user state (e.g. add items to a shopping cart) and the session ID (e.g. delete the session ID cookie when logging out). | ||
|
||
## Enabling experimental sessions | ||
|
||
In this early release of `experimental.sessions`, Astro's official server adapters have not yet been updated to provide a default session driver based on the platform's default storage feature. Until these are built in, you will have to specify a `driver` yourself in the `experimental.sessions` configuration object in addition to [adding an adapter](/en/guides/on-demand-rendering/#add-an-adapter). | ||
|
||
The following sections show the recommended drivers for each adapter. (These will be automatically configured for you in the stable release of this feature.) Alternatively, you can specify [any supported driver from unstorage](https://unstorage.unjs.io/drivers/). | ||
|
||
### Configuring sessions with the Node adapter | ||
|
||
The Node adapter is compatible with the the [filesystem driver](https://unstorage.unjs.io/drivers/fs). Note that this cannot be used in serverless environments as they have no shared filesystem. | ||
|
||
```js title="astro.config.mjs" ins={6} | ||
{ | ||
adapter: node({ mode: 'standalone' }), | ||
experimental: { | ||
session: { | ||
// Required: the name of the unstorage driver | ||
driver: "fs", | ||
}, | ||
}, | ||
} | ||
``` | ||
|
||
### Configuring a session driver for other adapters | ||
|
||
Choose the [unstorage `driver` name](https://unstorage.unjs.io/drivers/) that corresponds to the storage feature provided by your hosting platform, such as the [Netlify Blobs driver (`netlify-blobs`)](https://unstorage.unjs.io/drivers/netlify), the [Cloudflare KV driver (`cloudflare-kv-binding`)](https://unstorage.unjs.io/drivers/cloudflare) or the [Deno KV driver (`deno-kv`)](https://unstorage.unjs.io/drivers/deno). You can also use a cross-platform driver such as [Upstash](https://unstorage.unjs.io/drivers/upstash) or [Redis](https://unstorage.unjs.io/drivers/redis). | ||
|
||
:::note | ||
Some drivers may need extra packages to be installed. For example, the `netlify-blobs` driver requires the `@netlify/blobs` package, and Upstash requires the `@upstash/redis` package. Some drivers may also require environment variables or credentials to be set. | ||
|
||
<ReadMore>See [the unstorage driver docs](https://unstorage.unjs.io/drivers) for more information.</ReadMore> | ||
::: | ||
|
||
### Driver options | ||
|
||
You can also pass any available options to the unstorage driver in a separate `session.options` object. The following example configures the [Netlify Blobs](https://unstorage.unjs.io/drivers/netlify) driver while also providing a `name` and specifying a `consistency` mode: | ||
|
||
```js title="astro.config.mjs" ins={7-11} | ||
{ | ||
experimental: { | ||
adapter: netlify(), | ||
session: { | ||
// The name of the unstorage driver is camelCase | ||
driver: "netlify-blobs", | ||
options: { | ||
name: 'astro-sessions', | ||
// Sessions need strong consistency | ||
consistency: 'strong', | ||
} | ||
}, | ||
}, | ||
} | ||
``` | ||
|
||
## Using sessions | ||
|
||
Once you have configured a driver, you can use the `session` object to interact with the session. This object is accessible as `Astro.session` in your Astro components and pages and on the `context` object in API endpoints, middleware and actions. The API is the same in all cases. | ||
|
||
In most cases you will only need to use [`Astro.session.get()`](#sessionget) and [`Astro.session.set()`](#sessionset). For other available methods, see the [API section](#sessions-api). | ||
|
||
### Astro components and pages | ||
|
||
In `.astro` components and pages, you can access the session object via the global `Astro` object. For example, to display the number of items in a shopping cart: | ||
|
||
```astro title="src/components/CartButton.astro" "Astro.session" | ||
--- | ||
export const prerender = false; // Not needed in 'server' mode | ||
const cart = await Astro.session.get('cart'); | ||
--- | ||
<a href="/checkout">🛒 {cart?.length ?? 0} items</a> | ||
``` | ||
|
||
### API endpoints | ||
|
||
In API endpoints, the session object is available on the `context` object. For example, to add an item to a shopping cart: | ||
|
||
```ts title="src/pages/api/addToCart.ts" "context.session" | ||
import type { APIContext } from "astro"; | ||
|
||
export async function POST(req: Request, context: APIContext) { | ||
const cart = await context.session.get("cart"); | ||
cart.push(req.body.item); | ||
await context.session.set("cart", cart); | ||
return Response.json(cart); | ||
} | ||
``` | ||
|
||
### Actions | ||
|
||
In actions, the session object is available on the `context` object. For example, to add an item to a shopping cart: | ||
|
||
```ts title="src/actions/addToCart.ts" "context.session" | ||
import { defineAction } from "astro:actions"; | ||
import { z } from "astro:schema"; | ||
|
||
export const server = { | ||
addToCart: defineAction({ | ||
input: z.object({ productId: z.string() }), | ||
handler: async (input, context) => { | ||
const cart = await context.session.get("cart"); | ||
cart.push(input.productId); | ||
await context.session.set("cart", cart); | ||
return cart; | ||
}, | ||
}), | ||
}; | ||
``` | ||
|
||
### Middleware | ||
|
||
:::note | ||
Sessions are not currently supported in edge middleware. | ||
::: | ||
|
||
In middleware, the session object is available on the `context` object. For example, to set the last visit time in the session: | ||
|
||
```ts title="src/middleware.ts" "context.session" | ||
import { defineMiddleware } from 'astro:middleware'; | ||
|
||
export const onRequest = defineMiddleware(async (context, next) => { | ||
context.session.set('lastVisit', new Date()); | ||
return next(); | ||
}); | ||
``` | ||
|
||
## Cookies | ||
|
||
Sessions are generated when first accessed, and a session ID cookie is set in the response. No actual user data is stored in the cookie – just an ID that is used to identify a user's session. The session can be regenerated at any time with [`Astro.session.regenerate()`](#sessionregenerate), and destroyed with [`Astro.session.destroy()`](#sessiondestroy). | ||
|
||
### `session.cookie` | ||
|
||
<p> | ||
|
||
**Type:** `string` | `object`<br /> | ||
**Default:** `undefined`<br /> | ||
|
||
</p> | ||
|
||
An optional property to set cookie options. The `cookie.name` property can be automatically set by providing a string. To configure additional options, provide an object. | ||
|
||
```js title="astro.config.mjs" {5} ins={7-10} | ||
{ | ||
experimental: { | ||
session: { | ||
// If set to a string, this will be used as the cookie name | ||
// cookie: "my-session-id", | ||
// If set to an object, this will allow advanced options to be set | ||
cookie: { | ||
name: "my-session-id" | ||
sameSite: "Strict", | ||
}, | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Sessions API | ||
|
||
The session object is available in all Astro contexts, including components, actions, and API endpoints. In components, it is accessed via the global `Astro` object, and in actions and API endpoints it is available on the `context` object. The API is the same in all cases. | ||
|
||
Values are serialized and deserialized using [devalue](https://github.com/Rich-Harris/devalue), which is the same library used by content layer and actions. This means that supported types are the same, and include strings, numbers, `Date`, `Map`, `Set`, `URL`, arrays and plain objects. | ||
|
||
|
||
### `session.get()` | ||
|
||
<p> | ||
|
||
**Type**: `(key: string) => Promise<any>` | ||
</p> | ||
|
||
Returns the value of the given key in the session. If the key does not exist, it returns `undefined`. | ||
|
||
### `session.set()` | ||
|
||
<p> | ||
|
||
**Type**: `(key: string, value: any, options?: { ttl: number }) => void` | ||
</p> | ||
|
||
Sets the value of the given key in the session. The value can be any serializable type. | ||
|
||
### `session.regenerate()` | ||
|
||
<p> | ||
|
||
**Type**: `() => void` | ||
</p> | ||
|
||
Regenerates the session ID. Best practice is to call this when a user logs in or escalates their privileges, to prevent session fixation attacks. | ||
|
||
### `session.destroy()` | ||
|
||
<p> | ||
|
||
**Type**: `() => void` | ||
</p> | ||
|
||
Destroys the session, deleting the cookie and the object from the backend. This should be called when a user logs out or their session is otherwise invalidated. | ||
|
||
## Further reading | ||
|
||
For full details and to give feedback on this experimental API, see [the Sessions RFC](https://github.com/withastro/roadmap/blob/sessions/proposals/0054-sessions.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters