Authentication
The @wpnuxt/auth module provides WordPress authentication for your Nuxt app. It supports three authentication methods:
| Method | Description | WordPress Plugin |
|---|---|---|
| Password | Username/password login via GraphQL | Headless Login for WPGraphQL |
| External OAuth | Google, GitHub, etc. (recommended) | Headless Login for WPGraphQL |
| WordPress OAuth | Redirect to WordPress for login | miniOrange WP OAuth Server |
Feature Comparison
| Feature | Password | External OAuth | WordPress OAuth |
|---|---|---|---|
| Login method | Form in Nuxt | Google, GitHub, etc. | Redirect to WordPress |
| WPGraphQL compatible | ✅ | ✅ | ❌ |
| ✅ | ✅ | ✅ | |
| Username | ✅ | ✅ | ✅ |
| Display name | ✅ | ✅ | ✅ |
| Avatar | ✅ | ✅ | ❌ * |
| Roles | ✅ | ✅ | ❌ * |
| Logout | ✅ | ✅ | ✅ |
* WordPress OAuth (miniOrange) returns limited user data. Avatar and roles require miniOrange premium.
Installation
pnpm add @wpnuxt/auth
export default defineNuxtConfig({
modules: [
'@wpnuxt/core',
'@wpnuxt/auth'
]
})
Quick Start
<script setup>
const { login, isAuthenticated, error } = useWPAuth()
const form = reactive({ username: '', password: '' })
async function onSubmit() {
const result = await login(form)
if (result.success) {
navigateTo('/profile')
}
}
</script>
Configuration
export default defineNuxtConfig({
wpNuxtAuth: {
// Cookie settings
cookieName: 'wpnuxt-auth-token',
refreshCookieName: 'wpnuxt-refresh-token',
tokenMaxAge: 3600, // 1 hour
refreshTokenMaxAge: 604800, // 7 days
// Redirects
redirectOnLogin: '/',
redirectOnLogout: '/',
loginPage: '/login',
// Providers (see provider-specific docs)
providers: {
password: { enabled: true },
oauth: { enabled: false }
}
}
})
Composables
useWPAuth()
Main authentication composable.
const {
// State
user, // Current user (computed)
isAuthenticated, // Login status (computed)
isLoading, // Loading state (computed)
error, // Error message (computed)
// Methods
login, // Password login
loginWithOAuth, // WordPress OAuth (miniOrange)
loginWithProvider, // External OAuth (Google, GitHub, etc.)
logout, // Clear session
refresh, // Refresh token
getToken, // Get current token
getProviders, // Get available providers
hasPasswordAuth, // Check password auth
hasOAuthAuth, // Check WordPress OAuth auth
hasHeadlessLoginAuth, // Check external OAuth auth
fetchHeadlessLoginProviders // Fetch available external providers
} = useWPAuth()
useWPUser()
User data composable with role checking.
const {
user,
isLoading,
error,
fetchUser, // Fetch user from WordPress
clearUser, // Clear user state
hasRole, // Check specific role
isAdmin, // Check admin role
isEditor, // Check editor role
getDisplayName, // Get formatted name
getAvatarUrl // Get avatar URL
} = useWPUser()
How Authentication Works
The authentication flow works as follows:
1. User submits credentials
└─→ login() sends GraphQL mutation to WordPress
2. WordPress validates credentials
└─→ Returns JWT auth token + refresh token
3. WPNuxt stores tokens
└─→ Both stored in httpOnly cookies (not accessible to JavaScript)
4. Subsequent GraphQL requests
└─→ Auth token included automatically via cookies
5. Auth token expires (default: 1 hour)
└─→ Refresh token silently fetches a new auth token
6. Refresh token expires (default: 7 days)
└─→ User must log in again
The auth token is short-lived for security. The refresh token allows seamless session continuation without requiring the user to re-enter credentials on every visit. Both tokens are stored as httpOnly cookies, which protects them from XSS attacks.
SSR and Authentication
Because WPNuxt stores auth tokens in httpOnly cookies, authentication works seamlessly across server and client:
- Server-side rendering: Cookies are sent with server-side requests automatically, so
useWPUser()returns user data on the initial page load without a client-side fetch. - Auth middleware: Runs server-side on initial load and client-side on subsequent navigation. Protected pages are never rendered without authentication.
- Client-side navigation: After the initial server render, navigation between pages uses client-side requests that also include the cookies automatically.
http://localhost:3000/auth/callback.Debugging Authentication
If authentication isn't working, check these items in order:
- Verify the Headless Login plugin is installed: Open
schema.graphqlin your project root and search forlogin— if theloginmutation is missing, the plugin isn't active. Runpnpm dev:prepareafter activating it. - Check cookies in the browser: Open DevTools → Application → Cookies. After login, you should see
wpnuxt-auth-tokenandwpnuxt-refresh-tokencookies. - Enable debug mode: Set
WPNUXT_DEBUG=truein your.envfile for detailed auth logs in the server console. - Inspect GraphQL responses: In the browser Network tab, look at responses to GraphQL requests. Auth errors appear as
errorsin the JSON response with messages like "Invalid token" or "Expired token". - Test the login mutation directly: Open the WordPress GraphQL IDE at
https://your-wordpress.com/graphqland try running the login mutation manually to rule out WordPress-side issues.
Next Steps
- Password Authentication - Set up username/password login
- External OAuth Providers - Set up Google, GitHub, etc. (recommended)
- WordPress OAuth - Set up OAuth2 with WordPress (miniOrange)