> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify-han-update-changelogs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# JWT Auth

> Use a customized login flow to authenticate users

If you don’t have a dashboard, or if you want to keep your dashboard and docs completely separate, you can use your own login flow to send user info to your docs via a JWT in the URL.

## Implementation

<Steps>
  <Step title="Generate a private key">
    Go to your [Mintlify dashboard settings](https://dashboard.mintlify.com/settings/integrations) and generate a private key. Store this key somewhere secure where it can be accessed by your backend.
  </Step>

  <Step title="Create a login flow">
    Create a login flow that does the following:

    * Authenticate the user
    * Create a JWT containing the authenticated user's info in the [UserInfo](./sending-data) format
    * Sign the JWT with the secret, using the ES256 algorithm
    * Create a redirect URL back to your docs, including the JWT as the hash
  </Step>

  <Step title="Configure your User Auth settings">
    Return to your [Mintlify dashboard settings](https://dashboard.mintlify.com/settings/integrations) and add the login URL to your User Auth settings.
  </Step>
</Steps>

## Example

I want to set up authentication for my docs hosted at `docs.foo.com`. I want my docs
to be completely separate from my dashboard (or I don’t have a dashboard at all).

To set up authentication with Mintlify, I go to my Mintlify dashboard and generate a
JWT secret. I create a web URL `https://foo.com/docs-login` that initiates a login flow
for my users. At the end of this login flow, once I have verified the identity of the user,
I create a JWT containing the user’s custom data according to Mintlify’s specification.
I use a JWT library to sign this JWT with my Mintlify secret, create a redirect URL of the
form `https://docs.foo.com#{SIGNED_JWT}`, and redirect the user.

I then go to the Mintlify dashboard settings and enter `https://foo.com/docs-login` for the
Login URL field.

Here's what the code might look like:

```ts
import * as jose from 'jose';
import { Request, Response } from 'express';

const TWO_WEEKS_IN_MS = 1000 * 60 * 60 * 24 * 7 * 2;

const signingKey = await jose.importPKCS8(process.env.MINTLIFY_PRIVATE_KEY, 'ES256');

export async function handleRequest(req: Request, res: Response) {
  const userInfo = {
    expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000),
    groups: res.locals.user.groups,
    content: {
      firstName: res.locals.user.firstName,
      lastName: res.locals.user.lastName,
    },
  };

  const jwt = await new jose.SignJWT(userInfo)
    .setProtectedHeader({ alg: 'ES256' })
    .setExpirationTime('10 s')
    .sign(signingKey);

  return res.redirect(`https://docs.foo.com#${jwt}`);
}

```

## Preserving Anchors

Post-login, if you'd like to redirect to a specific anchor on the page, you can use the following format to create the redirect URL: `https://docs.foo.com/page#jwt={SIGNED_JWT}&anchor={ANCHOR}`.

Example:

* Original: `https://docs.foo.com/quickstart#step-one`
* Redirect: `https://docs.foo.com/quickstart#jwt={SIGNED_JWT}&anchor=step-one`
