# Authentication Tutorial
URL: https://www.quiltt.dev/get-started/tutorials/authentication
Description: Learn how to implement secure authentication with Quiltt's Auth API. Complete Next.js tutorial with code examples.
Navigation: get-started → tutorials → authentication
Tags: Tutorials
Content Length: 6k characters

Build a Next.js app that authenticates users, launches the Connector, and fetches financial data. Learn session token management and avoid rate limit errors.

**Time:** ~15 minutes
**Framework:** Next.js (concepts apply to any framework)

## What You'll Build

A Next.js app that:

1. Issues Session tokens server-side (protects your API key)
2. Caches tokens client-side (avoids rate limits)
3. Launches the Connector (lets users connect banks)
4. Fetches Profile data via GraphQL

## Session Tokens Explained

Session tokens authenticate users for the Connector and GraphQL API:

- **User-specific:** Each token is scoped to one Profile
- **24-hour lifespan:** Automatically expire
- **Client-safe:** Can be used in browser code
- **Rate limited:** 10/hour, 20/day per Profile

We'll use `QuilttAuthProvider` from `@quiltt/react` to handle token management automatically.

## Prerequisites

- [Quiltt Dashboard](https://dashboard.quiltt.dev) account
- Node.js 18+ installed
- Package manager (`pnpm`, `yarn`, or `npm`)

This tutorial uses `pnpm` but commands work with any package manager.

## 1. Project Setup

Create a Next.js project and install dependencies:

```bash
pnpm create next-app quiltt-auth-tutorial --typescript --tailwind --app
cd quiltt-auth-tutorial
pnpm add @quiltt/react
```

Add your credentials from the [Dashboard](https://dashboard.quiltt.dev):

```yaml
# .env.local
QUILTT_API_KEY_SECRET=your_api_key_secret_here
NEXT_PUBLIC_QUILTT_CONNECTOR_ID=your_connector_id_here
```

Warning:
Never commit `QUILTT_API_KEY_SECRET` to Git. It's for server-side use only.

Start the dev server:

```bash
pnpm dev
```

## 2. Issue Session Tokens

Create a server-side endpoint to issue tokens (this protects your API key from client-side exposure):

```ts
// app/api/quiltt-session/route.ts

  const requestBody = await req.json()

  const data = await fetch('https://auth.quiltt.io/v1/users/sessions', {
    method: 'POST',
    headers: {
      Authorization: `Bearer $[process.env.QUILTT_API_KEY_SECRET]`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestBody)
  })

  const session = await data.json()

  return NextResponse.json(session)
}

```

## 3. Set Up Authentication Provider

Fetch tokens and pass to `QuilttAuthProvider`. This handles session management, Connector auth, and GraphQL client setup.

```tsx
// app/providers.tsx
'use client'

  const [token, setToken] = useState()
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    async function loadSession() {
      // Check for cached token first
      const cached = localStorage.getItem(`quiltt_session_${quilttProfileId}`)

      if (cached) {
        const [token, expiresAt] = JSON.parse(cached)

        // Use cached token if still valid
        if (new Date(expiresAt) > new Date()) [setToken(token)
          setLoading(false)
          return]
      }

      // Fetch new token if no valid cached token
      const response = await fetch('/api/quiltt-session', {
        method: 'POST',
        headers: ['Content-Type': 'application/json'],
        body: JSON.stringify([userId: quilttProfileId])
      })

      const session = await response.json()

      // Cache the token with expiration
      localStorage.setItem(`quiltt_session_${quilttProfileId}`, JSON.stringify([token: session.token,
        expiresAt: session.expiresAt]))

      setToken(session.token)
      setLoading(false)
    }

    loadSession()
  }, [quilttProfileId])

  if (loading) return Loading...

  return (
    

QuilttAuthProvider:
[content]

  )
}
```

Destructive:
**Critical:** This code checks `localStorage` before issuing new tokens. Without caching, every page refresh issues a new token, quickly hitting the 10/hour rate limit.

Info:
Only need the Connector (not GraphQL)? Use `QuilttProvider` instead of `QuilttAuthProvider`.

## 4. Add Provider to Layout

Wire up the `Providers` component:

```tsx
// app/layout.tsx

  // Fetch this for the currently-logged user from your database or Auth provider
  const quilttProfileId = "p_12yz8qVmHucM2yqv09KfPv"

  return (
    

Html:

Body:

Providers:
[content]

  )
}
```

## 5. Launch the Connector

Add a button that launches the Connector (automatically authenticated):

```tsx
// app/page.tsx
'use client'

const CONNECTOR_ID = process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID

    

QuilttButton:
Launch Connector!

  )]

```

Visit [http://localhost:3000](http://localhost:3000) and click "Launch Connector":

![Tutorial app at localhost:3000 showing a "Launch Connector!" button centered on a dark page](./images/auth-connector-success.png)

## 6. Fetch Profile Data

Use `useQuilttClient` for GraphQL queries:

```tsx
// app/components/Welcome.tsx
'use client'

const PROFILE_QUERY = gql`
  query GetProfile {
    profile [id
      email]
  }
`

  const client = useQuilttClient()
  const [data, loading] = useQuery(PROFILE_QUERY, {client})

  if (loading) return Loading...

  return (
    

Welcome, [data?.profile?.email || data?.profile?.id]

  )
}

```

Add the `Welcome` component to your page:

```tsx
// app/page.tsx
'use client'

const CONNECTOR_ID = process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID

    [Welcome]

        

QuilttButton:
Launch Connector!

  )]
```

Refresh the page to see the greeting:

![Tutorial app at localhost:3000 showing the heading "Welcome, quiltty@quiltt.dev" above the "Launch Connector!" button after fetching profile data](./images/auth-great-success.png)

## Next Steps

**Continue Learning:**

- [Multi-Aggregator Connectors Tutorial](/get-started/tutorials/connectors) - Build a full connection flow with multiple providers
- [GraphQL Tooling Tutorial](/get-started/tutorials/graphql-tooling) - Set up type-safe GraphQL with code generation

**Reference Documentation:**

- [Session token best practices](/authentication/issuing-session-tokens#best-practices) - Caching and revocation strategies
- [Authentication overview](/authentication) - Complete authentication guide
- [GraphQL API reference](/api/graphql) - Available queries and mutations
- [Connector SDK docs](/connector/sdk/react) - Event handlers and customization