Authentication

Authentication

Add WordPress authentication to your Nuxt app

The @wpnuxt/auth module provides WordPress authentication for your Nuxt app. It supports three authentication methods:

MethodDescriptionWordPress Plugin
PasswordUsername/password login via GraphQLHeadless Login for WPGraphQL
External OAuthGoogle, GitHub, etc. (recommended)Headless Login for WPGraphQL
WordPress OAuthRedirect to WordPress for loginminiOrange WP OAuth Server

Feature Comparison

FeaturePasswordExternal OAuthWordPress OAuth
Login methodForm in NuxtGoogle, GitHub, etc.Redirect to WordPress
WPGraphQL compatible
Email
Username
Display name
Avatar❌ *
Roles❌ *
Logout

* WordPress OAuth (miniOrange) returns limited user data. Avatar and roles require miniOrange premium.

Recommendation: Use Password or External OAuth for full WPGraphQL compatibility. Use WordPress OAuth only when you need users to authenticate directly with WordPress.

Installation

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

Quick Start

pages/login.vue
<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

nuxt.config.ts
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.
OAuth callback URLs must point to your Nuxt app's URL (not your WordPress URL). The Nuxt server handles the OAuth callback and exchanges the authorization code for tokens. In local development, this is typically http://localhost:3000/auth/callback.

Debugging Authentication

If authentication isn't working, check these items in order:

  1. Verify the Headless Login plugin is installed: Open schema.graphql in your project root and search for login — if the login mutation is missing, the plugin isn't active. Run pnpm dev:prepare after activating it.
  2. Check cookies in the browser: Open DevTools → Application → Cookies. After login, you should see wpnuxt-auth-token and wpnuxt-refresh-token cookies.
  3. Enable debug mode: Set WPNUXT_DEBUG=true in your .env file for detailed auth logs in the server console.
  4. Inspect GraphQL responses: In the browser Network tab, look at responses to GraphQL requests. Auth errors appear as errors in the JSON response with messages like "Invalid token" or "Expired token".
  5. Test the login mutation directly: Open the WordPress GraphQL IDE at https://your-wordpress.com/graphql and try running the login mutation manually to rule out WordPress-side issues.

Next Steps

Copyright © 2026