> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Israel-Perez/Nuxt-Secure/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare Turnstile

> Configuring Cloudflare Turnstile CAPTCHA for login protection.

Nuxt Secure uses [Cloudflare Turnstile](https://www.cloudflare.com/products/turnstile/) to protect the login form from automated attacks. Users must pass a CAPTCHA challenge before their credentials are verified.

## Setup

<Steps>
  <Step title="Open the Cloudflare dashboard">
    Log in to your [Cloudflare dashboard](https://dash.cloudflare.com) and navigate to **Turnstile** in the sidebar.
  </Step>

  <Step title="Add a new site">
    Click **Add Site**, enter a name, and provide the domain where Nuxt Secure will be deployed. Cloudflare will generate a **Site Key** and a **Secret Key**.
  </Step>

  <Step title="Add the keys to your .env file">
    ```ini .env theme={null}
    NUXT_PUBLIC_TURNSTILE_SITE_KEY=your-site-key
    TURNSTILE_SECRET_KEY=your-secret-key
    ```
  </Step>
</Steps>

## How it works

The `@nuxtjs/turnstile` module (`^1.1.1`) is listed in the `modules` array of `nuxt.config.ts`. It automatically registers a `<NuxtTurnstile>` component and reads the site key from `turnstile.siteKey` (populated from `NUXT_PUBLIC_TURNSTILE_SITE_KEY`).

When the user submits the login form:

1. The browser includes a `turnstileToken` generated by the Turnstile widget.
2. The server API handler receives the token along with the user's credentials.
3. The server sends the token to Cloudflare's verification endpoint before processing the login:

```typescript server/api/auth/login.post.ts theme={null}
const verifyUrl = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'
const turnstileResponse = await fetch(verifyUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: `secret=${config.turnstile.secretKey}&response=${turnstileToken}`
})
```

4. If verification fails, the server responds with HTTP `400` and the message `"Fallo en la validación del captcha."` — no further login processing occurs.

## Local development

For local development, use Cloudflare's official test keys. These always pass verification without contacting Cloudflare's servers:

```ini .env theme={null}
NUXT_PUBLIC_TURNSTILE_SITE_KEY=1x00000000000000000000AA
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA
```

<Note>
  These test keys are provided by Cloudflare for development and CI use. Do not use them in production.
</Note>

<Warning>
  Without valid Turnstile keys, the CAPTCHA widget will not render and all login attempts will fail. Make sure both `NUXT_PUBLIC_TURNSTILE_SITE_KEY` and `TURNSTILE_SECRET_KEY` are set before running the application.
</Warning>

## Key reference

| Variable                         | Visibility       | Purpose                                                       |
| -------------------------------- | ---------------- | ------------------------------------------------------------- |
| `NUXT_PUBLIC_TURNSTILE_SITE_KEY` | Public (browser) | Renders the Turnstile widget in the login form.               |
| `TURNSTILE_SECRET_KEY`           | Server only      | Verifies the CAPTCHA token submitted with each login request. |
