Authentication

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:

composer require developer/wp-graphql-headless-login

Or download from: Headless Login for WPGraphQL

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:

SettingValue
Enable Password ProviderYes
Token Expiration3600 (1 hour)
Refresh Token Expiration604800 (7 days)
The plugin automatically adds login and refreshToken mutations to your GraphQL schema.

Nuxt Configuration

Password auth is enabled by default:

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

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

Usage

Login Form

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

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

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 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
Copyright © 2026