---
title: "Password Authentication"
description: "Set up username/password login with WordPress"
canonical_url: "https://wpnuxt.com/auth/password"
---
# Password Authentication

> Set up username/password login with WordPress

Password authentication sends credentials directly to WordPress via GraphQL. This is the simplest setup and works out of the box with the Headless Login plugin.

## WordPress Setup

### 1. Install Headless Login for WPGraphQL

Install the plugin from WordPress.org or via composer:

```bash
composer require developer/wp-graphql-headless-login
```

Or download from: [Headless Login for WPGraphQL](https://github.com/AxeWP/wp-graphql-headless-login)

### 2. Activate the Plugin

Go to **Plugins → Installed Plugins** and activate "Headless Login for WPGraphQL".

### 3. Configure the Plugin

Go to **GraphQL → Settings → Headless Login**:

<table>
<thead>
  <tr>
    <th>
      Setting
    </th>
    
    <th>
      Value
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Enable Password Provider
    </td>
    
    <td>
      Yes
    </td>
  </tr>
  
  <tr>
    <td>
      Token Expiration
    </td>
    
    <td>
      3600 (1 hour)
    </td>
  </tr>
  
  <tr>
    <td>
      Refresh Token Expiration
    </td>
    
    <td>
      604800 (7 days)
    </td>
  </tr>
</tbody>
</table>

<callout type="info">

The plugin automatically adds `login` and `refreshToken` mutations to your GraphQL schema.

</callout>

## Nuxt Configuration

Password auth is enabled by default:

```typescript [nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['@wpnuxt/core', '@wpnuxt/auth'],

  wpNuxtAuth: {
    providers: {
      password: { enabled: true }  // default
    }
  }
})
```

## Usage

### Login Form

```vue [pages/login.vue]
<script setup>
const { login, isLoading, error } = useWPAuth()
const router = useRouter()

const form = reactive({
  username: '',
  password: ''
})

async function onSubmit() {
  const result = await login({
    username: form.username,
    password: form.password
  })

  if (result.success) {
    router.push('/profile')
  }
}
</script>

<template>
  <form @submit.prevent="onSubmit">
    <input v-model="form.username" placeholder="Username" />
    <input v-model="form.password" type="password" placeholder="Password" />

    <p v-if="error" class="error">{{ error }}</p>

    <button type="submit" :disabled="isLoading">
      {{ isLoading ? 'Signing in...' : 'Sign in' }}
    </button>
  </form>
</template>
```

### Check Authentication

```vue [pages/profile.vue]
<script setup>
const { isAuthenticated, user, logout } = useWPAuth()
const { fetchUser, getDisplayName, getAvatarUrl } = useWPUser()

// Fetch full user data if authenticated
onMounted(async () => {
  if (isAuthenticated.value) {
    await fetchUser()
  }
})
</script>

<template>
  <div v-if="isAuthenticated">
    <img :src="getAvatarUrl()" />
    <h1>Welcome, {{ getDisplayName() }}</h1>
    <button @click="logout">Sign out</button>
  </div>
</template>
```

### Protect Routes

```typescript [middleware/auth.ts]
export default defineNuxtRouteMiddleware((to) => {
  const { isAuthenticated } = useWPAuth()
  const config = useRuntimeConfig().public.wpNuxtAuth

  if (!isAuthenticated.value && to.path !== config.loginPage) {
    return navigateTo(config.loginPage)
  }
})
```

## Security Considerations

Password authentication sends credentials over HTTPS:

- Credentials are encrypted in transit (TLS)
- Tokens are stored in cookies with `httpOnly` in production
- Refresh tokens allow sessions without re-authentication

For additional security, consider [OAuth authentication](https://wpnuxt.com/auth/oauth) which keeps passwords on WordPress.

## Troubleshooting

### "Login failed" error

1. Check WordPress user exists and password is correct
2. Verify Headless Login plugin is activated
3. Check GraphQL endpoint is accessible

### Token not refreshing

1. Verify refresh token cookie is set
2. Check `RefreshToken` mutation exists in schema
3. Ensure token expiration times match between Nuxt and WordPress


## Sitemap

See the full [sitemap](https://wpnuxt.com/sitemap.md) for all pages.
