# Fastify

## [Overview](/content/docs/sdk-examples/fastify#overview/index.html)

[Fastify](https://fastify.dev/) is a fast and low overhead web framework for Node.js, designed for building efficient server-side applications. This example demonstrates how to integrate **[Zitadel](/content/docs/index.html)** using the **[OAuth 2.0 PKCE flow](https://oauth.net/2/pkce/)** to authenticate users securely and maintain sessions across your application.

#### [Auth library](/content/docs/sdk-examples/fastify#auth-library/index.html)

This example uses **[@mridang/fastify-auth](https://www.npmjs.com/package/@mridang/fastify-auth)**, a [Fastify](https://fastify.dev/) plugin that wraps **[@auth/core](https://www.npmjs.com/package/@auth/core)** (formerly Auth.js). The underlying [@auth/core](https://authjs.dev/) library implements the [OpenID Connect (OIDC)](/content/docs/apis/openidoauth/endpoints/index.html) flow, manages [PKCE](https://oauth.net/2/pkce/), performs secure token exchange, and provides session management helpers. This integration leverages the **[@auth/core/providers/zitadel](https://authjs.dev/reference/core/providers/zitadel)** provider specifically designed for Zitadel authentication.

* * *

## [What this example demonstrates](/content/docs/sdk-examples/fastify#what-this-example-demonstrates/index.html)

This example shows a complete authentication implementation using [Fastify](https://fastify.dev/) with [server-side rendering](https://fastify.dev/) via [@fastify/view](https://www.npmjs.com/package/@fastify/view) and [Handlebars](https://handlebarsjs.com/) templates. The application implements secure user authentication through [Zitadel](/content/docs/index.html) using the industry-standard [PKCE flow](https://oauth.net/2/pkce/), which prevents authorization code interception attacks without requiring client secrets.

The example includes a custom sign-in page that initiates the [OAuth 2.0](/content/docs/guides/integrate/login/oidc/oauth-recommended-flows/index.html) authentication flow and automatic [callback handling](/content/docs/guides/integrate/login/oidc/login-users/index.html) with secure token exchange, and [JWT-based session management](/content/docs/apis/openidoauth/endpoints#token_endpoint/index.html) with [@fastify/cookie](https://www.npmjs.com/package/@fastify/cookie). Protected routes use the `requireAuth` middleware to automatically redirect unauthenticated users to the sign-in flow, ensuring only authenticated users can access sensitive areas. The profile page displays comprehensive user information including [OIDC claims](/content/docs/apis/openidoauth/claims/index.html) and [session metadata](/content/docs/apis/openidoauth/endpoints#token_endpoint/index.html).

The application also demonstrates proper **[federated logout](/content/docs/guides/integrate/login/oidc/logout/index.html)** by terminating sessions both locally and with Zitadel's [end-session endpoint](/content/docs/guides/integrate/login/oidc/logout/index.html), complete with CSRF protection using state parameters. Additionally, it includes automatic [token refresh](/content/docs/apis/openidoauth/endpoints/index.html) using [refresh tokens](/content/docs/apis/openidoauth/grant-types#refresh-token/index.html) to maintain long-lived sessions without requiring users to re-authenticate. The example uses [Zitadel-specific scopes](/content/docs/apis/openidoauth/scopes/index.html) like `urn:zitadel:iam:user:metadata` and `urn:zitadel:iam:org:projects:roles` to access extended user attributes and role information for implementing [role-based access control (RBAC)](/content/docs/guides/manage/console/roles/index.html).

* * *

## [Getting started](/content/docs/sdk-examples/fastify#getting-started/index.html)

### [Prerequisites](/content/docs/sdk-examples/fastify#prerequisites/index.html)

Before running this example, you need to create and configure a PKCE application in the [ZITADEL Management Console](/content/docs/guides/manage/console/console-overview/index.html). Follow the PKCE application setup guide to:

1. Create a new Web application in your [Zitadel project](/content/docs/guides/manage/console/projects-overview/index.html)
2. Configure it to use the PKCE authentication method
3. Set up your redirect URIs (e.g., `http://localhost:3000/auth/callback/zitadel` for development)
4. Configure post-logout redirect URIs (e.g., `http://localhost:3000/auth/logout/callback`)
5. Copy your **Client ID** for use in the next steps
6. Optionally enable [refresh tokens](/content/docs/apis/openidoauth/grant-types#refresh-token/index.html) in Token Settings for long-lived sessions

> **Note:** Make sure to enable **Dev Mode** in the [ZITADEL Management Console](/content/docs/guides/manage/console/console-overview/index.html) if you're using HTTP URLs during local development. For production, always use HTTPS URLs and disable Dev Mode.

### [Run the example](/content/docs/sdk-examples/fastify#run-the-example/index.html)

Once you have your [Zitadel application](/content/docs/guides/manage/console/applications-overview/index.html) configured:

1. Clone the [repository](https://github.com/zitadel/example-auth-fastify).
2. Create a `.env` file (copy from `.env.example`) and configure it with the values from your [Zitadel application](/content/docs/guides/manage/console/applications-overview/index.html). **Use these exact environment variable names:**

```
NODE_ENV=development
PORT=3000
SESSION_SECRET=your-very-secret-and-strong-session-key
SESSION_DURATION=3600
ZITADEL_DOMAIN=https://your-zitadel-domain
ZITADEL_CLIENT_ID=your-zitadel-application-client-id
ZITADEL_CLIENT_SECRET=
ZITADEL_CALLBACK_URL=http://localhost:3000/auth/callback/zitadel
ZITADEL_POST_LOGIN_URL=/profile
ZITADEL_POST_LOGOUT_URL=http://localhost:3000/auth/logout/callback
```

Replace these values with:
- Your actual [Zitadel instance URL](/content/docs/guides/manage/console/default-settings/index.html) for `ZITADEL_DOMAIN` (the issuer)
- The **Client ID** you copied when creating the application for `ZITADEL_CLIENT_ID`
- The **redirect URI** you configured in the PKCE setup for `ZITADEL_CALLBACK_URL` (must match exactly)
- The **post-logout redirect URI** for `ZITADEL_POST_LOGOUT_URL`
- A strong random string for `SESSION_SECRET` (generate using: `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"`)

3. Install dependencies using [npm](https://www.npmjs.com/) with `npm install` and start the development server with `npm run dev` to verify the authentication flow end-to-end.

* * *

## [Learn more and resources](/content/docs/sdk-examples/fastify#learn-more-and-resources/index.html)

- [PKCE concept](https://oauth.net/2/pkce/)
- [Federated logout](/content/docs/guides/integrate/login/oidc/logout/index.html)
- [OIDC integration guide](/content/docs/guides/integrate/login/oidc/login-users/index.html)
- [Fastify documentation](https://fastify.dev/)
- [Auth.js (Auth/Core)](https://www.npmjs.com/package/@auth/core)
- [Fastify Auth plugin](https://www.npmjs.com/package/@mridang/fastify-auth)
- [Example repository](https://github.com/zitadel/example-auth-fastify)
