> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Server-Side Rendering (SSR)

> Integrate Crossmint Auth on the server-side for user authentication and management

export const CreateApiKey = ({client, scopes, useJwt}) => {
  const scopeStr = (scope, index) => {
    if (index === scopes?.length - 1) {
      return <code>{scope}</code>;
    } else {
      return <span>
                    <code>{scope}</code>
                    <span>, </span>
                </span>;
    }
  };
  const localHostInAuthOrigin = client ? "http://localhost:3000" : "";
  return <div>
            <p>Navigate to the "Integrate" section on the left navigation bar, and ensure you're on the "API Keys" tab.</p>
            <p>
                Within the <b>{client ? "Client-side" : "Server-side"} keys</b> section, click the "Create new key"
                button in the top right.
            </p>
            {client ? <p>
                    On the authorized origins section, enter <code>http://localhost:3000</code> and click "Add origin".
                </p> : ""}
            {scopes && scopes.length > 0 && <p>
                    Next, check the scopes labeled {scopes.map((scope, index) => <span key={index}>{scopeStr(scope, index)}</span>)}.
                </p>}
            {useJwt ? <p>
                    Check the "JWT Auth" box.
                </p> : ""}
            <p>
                Finally, create your key and save it for subsequent steps.
            </p>
        </div>;
};

<Snippet file="auth-staging-note.mdx" />

Crossmint Auth provides a flexible and simple authentication solution for your crypto server-side applications. This guide covers how to integrate and use Crossmint Auth across various server-side frameworks.

## Overview

Our server SDK allows you to:

* Manage user sessions
* Retrieve user profiles
* Verify JSON Web Tokens (JWTs)

## Installation

First, install the Crossmint Server SDK:

<CodeGroup>
  ```bash npm theme={null}
  npm i @crossmint/server-sdk
  ```

  ```bash yarn theme={null}
  yarn add @crossmint/server-sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @crossmint/server-sdk
  ```

  ```bash bun theme={null}
  bun add @crossmint/server-sdk
  ```
</CodeGroup>

## Initialization

To use Crossmint Auth, you need to initialize it with your Server API key. This API requires the `users.read` scope.

```typescript theme={null}
import { createCrossmint, CrossmintAuth } from "@crossmint/server-sdk";

const crossmint = createCrossmint({ apiKey: process.env.SERVER_CROSSMINT_API_KEY });
const crossmintAuth = CrossmintAuth.from(crossmint);
```

## Core Functionality

### Session Management

The `getSession` method validates or refreshes a user's session based on their JWT and refresh token.

```typescript theme={null}
const { jwt, refreshToken, userId } = await crossmintAuth.getSession(req, res);
```

This method:

1. Fetches the current JWT and refresh token from the cookies with keys `crossmint-jwt` and `crossmint-refresh-token`.
2. Checks if the current JWT is valid
3. Refreshes the session if needed
4. Stores the new JWT and refresh token in cookies
5. Returns new auth materials and the user ID

<Tabs>
  <Tab title="Next.js (App Router)">
    For other frameworks that do not expose standard request and response objects, such as Next.js using the App Router, you can pass in an object with `jwt` and `refreshToken` properties instead:

    <CodeGroup>
      ```typescript middleware.ts theme={null}
      import { NextResponse } from "next/server";
      import type { NextRequest } from "next/server";
      import { createCrossmint, CrossmintAuth } from "@crossmint/server-sdk";

      export async function middleware(request: NextRequest) {
          // Skip middleware for API routes and static files
          if (request.nextUrl.pathname.startsWith("/api") || request.nextUrl.pathname.startsWith("/_next")) {
              return NextResponse.next();
          }

          const response = NextResponse.next();

          const jwt = request.cookies.get("crossmint-jwt")?.value;
          const refreshToken = request.cookies.get("crossmint-refresh-token")?.value;

          if (refreshToken == null) {
              return response;
          }

          try {
              const crossmint = createCrossmint({
                  apiKey: process.env.SERVER_CROSSMINT_API_KEY || "",
              });
              const crossmintAuth = CrossmintAuth.from(crossmint);

              const { jwt: newJwt, refreshToken: newRefreshToken } = await crossmintAuth.getSession({
                  jwt,
                  refreshToken,
              });

              // Only update response cookies if tokens have changed
              if (newJwt !== jwt || newRefreshToken.secret !== refreshToken) {
                  response.cookies.set("crossmint-jwt", newJwt);
                  response.cookies.set("crossmint-refresh-token", newRefreshToken.secret);
              }
          } catch (_) {
              // If auth fails, clear cookies and redirect to home
              response.cookies.delete("crossmint-jwt");
              response.cookies.delete("crossmint-refresh-token");
          }

          return response;
      }
      ```

      ```typescript getAuthSession.ts theme={null}
      import { cookies } from "next/headers";
      import { createCrossmint, CrossmintAuth } from "@crossmint/server-sdk";

      export async function getAuthSession() {
          const cookieStore = await cookies();
          const jwt = cookieStore.get("crossmint-jwt")?.value;
          const refreshToken = cookieStore.get("crossmint-refresh-token")?.value;

          if (refreshToken == null) {
              return;
          }

          try {
              const crossmint = createCrossmint({
                  apiKey: process.env.SERVER_CROSSMINT_API_KEY || "",
              });
              const crossmintAuth = CrossmintAuth.from(crossmint);

              const session = await crossmintAuth.getSession({
                  jwt,
                  refreshToken,
              });
              return session;
          } catch (_) {
              return;
          }
      }
      ```

      ```typescript page.tsx theme={null}
      import { getAuthSession } from "@/hooks/auth";
      import { createCrossmint, CrossmintAuth } from "@crossmint/server-sdk";

      export default async function ProtectedRoute() {
        const session = await getAuthSession();
        const userId = session?.userId;

        if (userId != null) {
          // Fetch user data or perform authorized actions
          const crossmint = createCrossmint({
              apiKey: process.env.SERVER_CROSSMINT_API_KEY || "",
          });
          const crossmintAuth = CrossmintAuth.from(crossmint);
          const userData = await crossmintAuth.getUser(userId);

          return <div>Welcome, {userData.email}!</div>;
        }

        // Handle unauthenticated state
        return <div>Please log in to access this page.</div>;
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Express.js">
    For Express.js applications, you can create middleware to handle authentication:

    ```typescript theme={null}
    import express from "express";
    import { createCrossmint, CrossmintAuth } from "@crossmint/server-sdk";

    const app = express();

    const crossmint = createCrossmint({
        apiKey: process.env.SERVER_CROSSMINT_API_KEY || "",
    });
    const crossmintAuth = CrossmintAuth.from(crossmint);

    const authMiddleware = async (req, res, next) => {
      try {
        const { jwt, refreshToken, userId } = await crossmintAuth.getSession(req, res);
        req.user = { userId };
        next();
      } catch (error) {
        res.status(401).json({ error: "Authentication failed" });
      }
    };

    app.use(authMiddleware);

    app.get("/protected", (req, res) => {
      res.json({ message: "Protected route", userId: req.user.userId });
    });
    ```
  </Tab>

  <Tab title="Vanilla Node.js">
    For a basic Node.js server:

    ```typescript theme={null}
    import http from "http";
    import { createCrossmint, CrossmintAuth } from "@crossmint/server-sdk";

    const crossmint = createCrossmint({
        apiKey: process.env.SERVER_CROSSMINT_API_KEY || "",
    });
    const crossmintAuth = CrossmintAuth.from(crossmint);

    const server = http.createServer(async (req, res) => {
      if (req.url === "/protected") {
        try {
          const { userId } = await crossmintAuth.getSession(req, res);
          const userData = await crossmintAuth.getUser(userId);

          res.writeHead(200, { "Content-Type": "application/json" });
          res.end(JSON.stringify({ message: "Authenticated", user: userData }));
        } catch (error) {
          res.writeHead(401, { "Content-Type": "application/json" });
          res.end(JSON.stringify({ error: "Authentication failed" }));
        }
      } else {
        res.writeHead(404);
        res.end();
      }
    });

    server.listen(3000);
    ```
  </Tab>
</Tabs>

### User Profile Retrieval

Fetch user details using the `getUser` method:

```typescript theme={null}
const user = await crossmintAuth.getUser(userId);
```

This provides access to user information such as email, phone number, and connected accounts (e.g., Twitter, Farcaster).

### JWT Verification

Verify JWTs independently using the `verifyCrossmintJwt` method:

```typescript theme={null}
const decodedJwt = crossmintAuth.verifyCrossmintJwt(token);
```

This is useful for validating tokens in middleware or specific endpoints. We expose our public keys for this purpose at [https://www.crossmint.com/.well-known/jwks.json](https://www.crossmint.com/.well-known/jwks.json).
