Getting Started
@riavzon/auth-h3client connects your Nuxt or Nitro application to a running IAM service. The module registers server middleware, auto-imports server utilities and client composables, and wires up the authentication routes in a single Nitro plugin call.
Requirements
- Node.js 22 or later
- Nuxt 3 and later or a Nitro/H3 application
- A running IAM service reachable from your server
Installation
pnpm add @riavzon/auth-h3client
yarn add @riavzon/auth-h3client
npm install @riavzon/auth-h3client
bun add @riavzon/auth-h3client
Nuxt module setup
If you are using Nuxt, use the dedicated module. It handles auto-imports and can register the bundled middleware for you, while your Nitro plugin provides the runtime configuration.
Register the module in nuxt.config.ts. This enables the auto-import of all server utilities and client composables, and optionally registers the global security middleware.
export default defineNuxtConfig({
modules: ['auth-h3client/module'],
authH3Client: {
enableMiddleware: true,
authStatusUrl: '/api/auth/users/authStatus',
registerApiRoute: {
path: '/api/auth/api-tokens'
}
}
})
defineAuthenticatePublicApi, do not run the global auth middleware on those
paths. That middleware runs isIPValid, botDetectorMiddleware, and
generateCsrfCookie, which regular browser auth requests still need, but
repeated API-key verification traffic can be rate-limited or banned by the bot
detector. In mixed apps, set enableMiddleware: false and register your own
server middleware so those API-key routes bypass the browser middleware chain.
The module still registers the auth status route and, when configured, the
optional API token list route.Read the Nuxt Module Documentation for full configuration and usage.
H3 v1 H3 v2
This module supports both H3 v1 and H3 v2. Choose the matching entry point for your H3 version:
- H3 v1 (default): import from auth-h3client or auth-h3client/v1. supported version:
h3@^1.15.4. - H3 v2: import from auth-h3client/v2. supported version:
h3@^2.0.0-beta.4.
Register the routes
import { createApp, createRouter } from "h3";
import { configuration, httpLogger, useAuthRoutes, useOAuthRoutes, magicLinksRouter, bounceRouter } from 'auth-h3client';
configuration(config);
const app = createApp();
httpLogger()(app);
app.use(isIPValid);
app.use(botDetectorMiddleware);
app.use(generateCsrfCookie);
const router = createRouter();
useAuthRoutes(router);
useOAuthRoutes(router);
bounceRouter(router);
magicLinksRouter(router, 'api');
router.get('/auth/users/authStatus', getAuthStatusHandler)
app.use(router);
// Your handlers
import { H3 } from 'h3'
import {
configuration,
httpLogger,
isIPValid,
botDetectorMiddleware,
generateCsrfCookie,
useAuthRoutes,
magicLinksRouter,
useOAuthRoutes,
getAuthStatusHandler
} from 'auth-h3client/v2';
configuration(config);
const app = new H3()
// v2 logger is a plugin: register directly
app.register(httpLogger())
app.use(isIPValid);
app.use(botDetectorMiddleware);
app.use(generateCsrfCookie);
useAuthRoutes(app);
useOAuthRoutes(app);
bounceRouter(app);
magicLinksRouter(app, 'api');
app.get('/auth/users/authStatus', getAuthStatusHandler)
// Your handlers
Nitro
Make a Nitro plugin:
import { defineNitroPlugin } from "nitro";
import { configuration, httpLogger, useAuthRoutes, useOAuthRoutes, magicLinksRouter, bounceRouter } from 'auth-h3client';
import { configDefaults } from 'auth-h3client/server/templates'
export default defineNitroPlugin((nitro) => {
configuration({
...configDefaults,
uStorage: {
storage: useStorage('cache'),
cacheOptions: {
successTtl: 60 * 60 * 24 * 30,
rateLimitTtl: 10
}
}
});
httpLogger()(nitro.h3App);
nitro.h3App.use(isIPValid)
nitro.h3App.use(botDetectorMiddleware)
nitro.h3App.use(generateCsrfCookie)
useAuthRoutes(nitro.router);
useOAuthRoutes(nitro.router);
bounceRouter(nitro.router);
magicLinksRouter(nitro.router, 'api');
})
auth-h3client/v2Read the H3 and Nitro Setup guide to learn more.
Configuring the Module
Before using any exported handlers you must call the configuration function exactly once at boot:
import { configuration } from 'auth-h3client';
import { createStorage } from 'unstorage';
import memoryDriver from 'unstorage/drivers/memory';
const storage = createStorage({ driver: memoryDriver() });
configuration({
server: {
auth_location: {
serverOrDNS: process.env.AUTH_API_HOST ?? '127.0.0.1',
port: Number(process.env.AUTH_API_PORT ?? 10000),
},
hmac: {
enableHmac: true,
clientId: process.env.AUTH_CLIENT_ID!,
sharedSecret: process.env.AUTH_SHARED_SECRET!,
},
ssl: {
enableSSL: false,
},
cryptoCookiesSecret: process.env.COOKIE_SECRET!,
},
uStorage: {
storage: storage,
cacheOptions: {
successTtl: 60 * 60 * 24 * 30,
rateLimitTtl: 10
}
},
onSuccessRedirect: 'https://app.example.com/dashboard',
OAuthProviders: [
{
kind: 'oidc',
name: 'google',
issuer: 'https://accounts.google.com',
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
defaultScopes: ['openid', 'email', 'profile'],
redirectUri: 'https://app.example.com/oauth/callback/google',
supportPKCE: true,
redirectUrlOnSuccess: 'https://app.example.com/dashboard',
redirectUrlOnError: 'https://app.example.com/login',
},
],
logLevel: 'info',
});
Verify the setup
Start your development server and make a request to the auth status endpoint.
Under the Nuxt module, the default path is /api/auth/users/authStatus. With
no active session the response should be:
curl http://localhost:3000/api/auth/users/authStatus
{
"authorized": false
}
A __Host-csrf cookie should also be present on the response. If the IAM service is unreachable, the auth status handler returns { "authorized": false } rather than erroring, so check the server logs if you expect a different result.