API & Composable Reference
Complete reference for useBearerAuth composable, types, server handlers, server utilities, and public type exports.
Reference & Recipes Nuxt 4 / TypeScript
useBearerAuth() / useAuth()
typescript
import { useBearerAuth, useAuth } from '#imports'
const auth = useBearerAuth<CustomUser>()
Reactive State Properties
| Property | Type | Description | | :--- | :--- | :--- | |user | Ref<User | null> | Current authenticated user profile object. |
| status | Ref<AuthStatus> | 'idle' | 'loading' | 'authenticated' | 'unauthenticated'. |
| ready | Ref<boolean> | true once initial auth check (SSR or client) has resolved. |
| error | Ref<string | null> | Last authentication error message string. |
| abilities | Ref<string[] | null> | Normalized ability strings hydrated from the server session; powers the advisory can() / cannot() checks. |
| loading | ComputedRef<boolean> | Convenience computed shorthand for status.value === 'loading'. |
| isAuthenticated | ComputedRef<boolean> | Convenience computed shorthand for status.value === 'authenticated'. |
| serverReady | ComputedRef<Promise<void>> | Resolves when server-side auth hydration completes. Used internally by the global middleware. |
Composable Methods
typescript
// 1. Login with credentials
login(credentials: LoginCredentials, redirectPath?: string | null): Promise<AuthApiResponse<User>>
// 2. Social login with OAuth provider JWT/Token
socialLogin(credentials: SocialLoginCredentials, redirectPath?: string | null): Promise<AuthApiResponse<User>>
// 3. Register a new user
register(payload: Record<string, unknown>, redirectPath?: string | null): Promise<AuthApiResponse<User>>
// 4. Verify OTP code
verifyOtp(payload: Record<string, unknown>, redirectPath?: string | null): Promise<AuthApiResponse<User>>
// 5. Fetch current user from /api/auth/me
fetchUser(options?: FetchUserOptions): Promise<{ data: User | null; error: string | null }>
// 6. Silent token refresh
refresh(): Promise<AuthApiResponse<User>>
// 7. Logout and destroy session
logout(destination?: string): Promise<void>
// 8. Forgot password request
forgotPassword(payload: Record<string, unknown>): Promise<any>
// 9. Reset password request
resetPassword(payload: Record<string, unknown>): Promise<any>
// 10. Resend OTP code
resendOtp(identifier: string, payload?: Record<string, unknown>): Promise<any>
// 11. Clear client auth state manually
clearAuthState(): void
// 12. Advisory ability check — exact string match against auth.abilities
can(ability: string): boolean
// 13. Inverse of can()
cannot(ability: string): boolean
Built-in Server API Routes
The module mounts these Nitro handlers underroutes.localApiPrefix (default: /api/auth):
| Method & Route | Backend Endpoint Forwarded | Description |
| :--- | :--- | :--- |
| POST /api/auth/login | endpoints.login | Authenticates user, creates Redis session, sets cookie. |
| POST /api/auth/social-login | endpoints.socialLogin | Passes OAuth token to backend, creates Redis session. |
| POST /api/auth/logout | endpoints.logout | Destroys Redis session and cookie; calls backend logout (continues even if backend is unreachable). |
| GET /api/auth/me | endpoints.me | Returns current user from Redis session cache or refreshes from backend if ?refresh=true. |
| POST /api/auth/refresh | endpoints.refresh | Calls backend refresh using Redis-held refresh token, updates session. New token is not returned to browser. |
| POST /api/auth/register | endpoints.register | Forwards registration payload. Creates session if backend returns a token. |
| POST /api/auth/otp-verification| endpoints.verifyOtp | Forwards OTP verification payload. Creates session if backend returns a token. |
| POST /api/auth/resend-otp/:id | endpoints.resendOtp | Triggers OTP resend for given user identifier. |
| POST /api/auth/forgot-password | endpoints.forgotPassword| Forwards forgot-password email/payload. |
| POST /api/auth/reset-password | endpoints.resetPassword | Forwards password reset payload with token. |
| GET /api/auth/sessions | Local Redis | Lists active sessions for current user as { sessions: PublicSession[] }. |
| DELETE /api/auth/sessions/:id | Local Redis | Revokes specific session ID after verifying ownership. |
Server Utilities
When writing custom Nitro endpoints in your application, import these utilities from#imports:
typescript
import {
// Session read/write
getBearerAuthSession, // Read session from Redis by cookie
createBearerAuthSession, // Create new session after authentication
updateBearerAuthSession, // Update token, refreshToken, or profile in session
destroyBearerAuthSession, // Delete session from Redis and clear cookie
destroyAllBearerAuthSessions, // Delete all sessions for a user ID
getUserBearerAuthSessions, // List PublicSession[] for a user (no tokens)
deleteUserBearerAuthSession, // Delete a specific session with ownership check
// Guard utility
requireBearerAuthSession, // Read event.context.auth or throw 401
// External API proxy
callAuthApi, // Make authenticated request to backend using session token
// Redis client (advanced use)
getBearerAuthRedisClient,
} from '#imports'
requireBearerAuthSession(event) reads from event.context.auth (populated by the server middleware) and throws a 401 Unauthenticated error if no valid session is present. It does not make an additional Redis query — the session is already attached to the event context by the time your handler runs.
requireAbility(event, abilities, mode?) enforces authorization on top of authentication: it throws 401 Unauthenticated when no session exists and 403 Authorization required when the session lacks the required ability. It is imported from the server-only subpath nuxt-bearer-auth/server rather than #imports so it never reaches client bundles. See the Authorization guide.
callAuthApi(endpoint, options) constructs an HTTP request to your backend using apiBaseUrl + endpoint. When an event is provided, it automatically retrieves the bearer token from the Redis session and injects it as an Authorization: Bearer header. The token is never passed through the browser.
The nuxt-bearer-auth/server subpath also exports the supporting primitives requireAbility() builds on: normalizeAuthorizationData(), extractAuthorizationFromResponse(), and hasRequiredAbilities(). Treat requireAbility() as the primary API — the others are the same normalization and matching helpers the module uses internally, exported for custom enforcement code.
UI Authorization Components
Two auto-imported components expose declarative authorization over the same client ability state that powerscan()/cannot(). Full usage guidance lives in the Authorization guide.
| Component | Renders its default slot when |
| --- | --- |
| <Can> | The current abilities satisfy the requirement. |
| <Cannot> | They do not — the exact negation of <Can>, with no separate matching logic. |
Shared props: ability?: string (single ability, wins over abilities), abilities?: string[] (evaluated with mode), and mode?: 'all' | 'any' (default 'all'). An optional #fallback slot renders when the check denies, and denied slot content is removed from the DOM. Evaluation is reactive to login, refresh, logout, and session replacement, deterministic across SSR and hydration, and fails closed on malformed props or malformed ability state. An empty requirement means unrestricted.
vue
<Can ability="users.delete">
<button>Delete user</button>
<template #fallback>
<span>You do not have permission to delete users.</span>
</template>
</Can>
Components control visibility only — they never secure API requests. Enforce authorization in Nitro handlers with
requireAbility(), and always enforce it again on your backend.
TypeScript Types
typescript
export type AuthStatus = 'idle' | 'loading' | 'authenticated' | 'unauthenticated'
export interface BearerAuthUser {
id?: string | number
uuid?: string
email?: string
name?: string
[key: string]: unknown // Open-ended — your backend user shape
}
export interface BearerAuthSession<User extends BearerAuthUser = BearerAuthUser> {
userId: string
token: string // Bearer token — server-side only
refreshToken?: string | null
profile: User | null
createdAt: string // ISO timestamp
expiresAt: number // Epoch milliseconds (application-level expiry guard)
lastActivity: string // ISO timestamp — updated on each authenticated request
userAgent?: string
ipAddress?: string
abilities?: string[] | null // Normalized ability strings — server-derived
}
// Safe public shape — omits token, refreshToken, userId, expiresAt
export interface PublicSession {
id: string
createdAt: string
lastActivity: string
userAgent?: string
ipAddress?: string
}
export interface AuthApiResponse<T = unknown> {
success: boolean
message?: string
data?: T
user?: BearerAuthUser | null
code?: string | number
nextAction?: string
}
export interface LoginCredentials {
identifier?: string
email?: string
username?: string
phone?: string
mobile?: string
password?: string
[key: string]: unknown
}
export interface SocialLoginCredentials {
jwt?: string
token?: string
provider?: string
[key: string]: unknown
}
export interface FetchUserOptions {
refresh?: boolean
}
Public Type Exports
All core authentication types are exported from the package root and can be imported directly in your application:
typescript
import type {
// Auth state and response types
AuthStatus,
AuthApiResponse,
BearerAuthUser,
BearerAuthSession,
PublicSession,
// Credential types
LoginCredentials,
SocialLoginCredentials,
FetchUserOptions,
// Module configuration types
BearerAuthModuleOptions,
BearerAuthEndpointOptions,
BearerAuthResponsePaths,
BearerAuthRedirectOptions,
BearerAuthRouteOptions,
BearerAuthCookieOptions,
BearerAuthCsrfOptions,
// Authorization types
Ability,
AuthorizationSource,
AuthorizationMatchMode,
AuthorizationRouteRequirement,
AuthorizationResponsePaths,
AuthorizationState,
BearerAuthAuthorizationConfig,
} from 'nuxt-bearer-auth'
These types are useful when extending the module, writing typed custom middleware, building strongly-typed composables around
useBearerAuth, or constructing typed server API handlers.
typescript
// Example: extending BearerAuthUser with your own fields
import type { BearerAuthUser } from 'nuxt-bearer-auth'
interface AppUser extends BearerAuthUser {
role: 'admin' | 'editor' | 'viewer'
organizationId: string
avatarUrl?: string
}
// Pass your type to the composable for full type inference
const auth = useBearerAuth<AppUser>()
// auth.user.value is now typed as AppUser | null
console.log(auth.user.value?.role)
Testing Foundation
nuxt-bearer-auth ships with a comprehensive automated test suite to give you confidence in the authentication and authorization foundation you are building on.
Test runner: Vitest
Test results: 15 test files · 163 tests · 163 passing (verified after the Phase 4 UI authorization release)The suite covers:
| Suite | What it tests | | :--- | :--- | |sessions.test.ts | Session creation, retrieval, update, sliding TTL, destroy, destroy-all, multi-device listing, per-user revocation, requireBearerAuthSession |
| auth-handlers.test.ts | Login, social login, logout resilience, token refresh, /me cached vs. forced refresh |
| otp-register.test.ts | OTP verification flow, registration with and without auto-login |
| server-middleware.test.ts | Public route bypass, safe method bypass, authenticated context attachment, 401 on protected routes |
| route-middleware.test.ts | Client route guard — public access, protected redirect, auth-page redirect for authenticated users, Phase 3 authorization metadata enforcement (disabled mode inert, all/any modes, exact matching, custom unauthorized route, fail-closed malformed client state) |
| authorization-normalization.test.ts | Abilities/roles/permissions normalization into sorted unique strings, disabled/missing configuration safety |
| authorization-client.test.ts | Client ability synchronization across login/refresh/me, omission preservation, logout clearing stale abilities |
| authorization-enforcement.test.ts | Server requireAbility() — 401 vs 403, all/any semantics, exact matching, fail-closed malformed session data, rejection of client-supplied state/headers/query |
| authorization-ui-evaluator.test.ts | Pure Phase 4 evaluator — all/any modes, exact and case-sensitive matching, wildcard/prefix/role non-implication, empty requirements unrestricted, fail-closed malformed state and requirements, input immutability |
| authorization-ui-components.test.ts | <Can>/<Cannot> component matrix — prop normalization and precedence, fallback slots, reactivity to login/logout/refresh, SSR determinism, fail-closed behavior |
| ssr-plugin.test.ts | SSR hydration with valid session, unauthenticated SSR, Redis error resilience |
| normalize.test.ts | Response path normalization for multiple backend response shapes |
| paths.test.ts | JSON path traversal, $ root selector, dot notation, null safety, URL interpolation |
| errors.test.ts | FetchError normalization, H3 error passthrough, generic error → 500 |
| redis-reliability.test.ts | Edge cases: missing cookie, missing session key, partial context |Run the tests yourself:
bash
# In the nuxt-bearer-auth package directory
npm test