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:
| Setting | Value |
|---|---|
| Enable Password Provider | Yes |
| Token Expiration | 3600 (1 hour) |
| Refresh Token Expiration | 604800 (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
httpOnlyin production - Refresh tokens allow sessions without re-authentication
For additional security, consider OAuth authentication which keeps passwords on WordPress.
Troubleshooting
"Login failed" error
- Check WordPress user exists and password is correct
- Verify Headless Login plugin is activated
- Check GraphQL endpoint is accessible
Token not refreshing
- Verify refresh token cookie is set
- Check
RefreshTokenmutation exists in schema - Ensure token expiration times match between Nuxt and WordPress