---
title: "Authentication"
description: "Add WordPress authentication to your Nuxt app"
canonical_url: "https://wpnuxt.com/auth"
---
# Authentication

> Add WordPress authentication to your Nuxt app

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

<table>
<thead>
  <tr>
    <th>
      Method
    </th>
    
    <th>
      Description
    </th>
    
    <th>
      WordPress Plugin
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Password
    </td>
    
    <td>
      Username/password login via GraphQL
    </td>
    
    <td>
      Headless Login for WPGraphQL
    </td>
  </tr>
  
  <tr>
    <td>
      External OAuth
    </td>
    
    <td>
      Google, GitHub, etc. (recommended)
    </td>
    
    <td>
      Headless Login for WPGraphQL
    </td>
  </tr>
  
  <tr>
    <td>
      WordPress OAuth
    </td>
    
    <td>
      Redirect to WordPress for login
    </td>
    
    <td>
      miniOrange WP OAuth Server
    </td>
  </tr>
</tbody>
</table>

## Feature Comparison

<table>
<thead>
  <tr>
    <th>
      Feature
    </th>
    
    <th>
      Password
    </th>
    
    <th>
      External OAuth
    </th>
    
    <th>
      WordPress OAuth
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Login method
    </td>
    
    <td>
      Form in Nuxt
    </td>
    
    <td>
      Google, GitHub, etc.
    </td>
    
    <td>
      Redirect to WordPress
    </td>
  </tr>
  
  <tr>
    <td>
      WPGraphQL compatible
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ❌
    </td>
  </tr>
  
  <tr>
    <td>
      Email
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      Username
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      Display name
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      Avatar
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ❌ *
    </td>
  </tr>
  
  <tr>
    <td>
      Roles
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ❌ *
    </td>
  </tr>
  
  <tr>
    <td>
      Logout
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
</tbody>
</table>

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

<callout type="success">

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

</callout>

## Installation

```bash
pnpm add @wpnuxt/auth
```

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

## Quick Start

```vue [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

```typescript [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.

```typescript
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.

```typescript
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:

```text
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.

<callout type="warning">

**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`.

</callout>

## 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

- [Password Authentication](https://wpnuxt.com/auth/password) - Set up username/password login
- [External OAuth Providers](https://wpnuxt.com/auth/headless-login) - Set up Google, GitHub, etc. (recommended)
- [WordPress OAuth](https://wpnuxt.com/auth/oauth) - Set up OAuth2 with WordPress (miniOrange)


## Sitemap

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