Securing Nuxt API Routes with Nitro Utils
Centralizing session validation through a reusable secure handler wrapper eliminates repetitive auth checks and improves maintainability.
Summary
Rather than repeating session-validation code in every protected API endpoint, create a defineSecureHandler utility that wraps handlers and validates sessions centrally. The pattern improves maintainability and ensures consistent auth behavior across all protected routes.
Key Concepts
nuxt-auth-utils setup: The foundation uses setUserSession() for login and useUserSession() composable for checking auth state.
Route middleware: An auth middleware checks for active sessions and redirects unauthenticated users from protected pages.
Secure handler pattern: The core innovation wraps route handlers with session validation:
// server/utils/auth.ts
export function defineSecureHandler<T>(
handler: (event: H3Event, user: User) => T
) {
return defineEventHandler(async (event) => {
const session = await getUserSession(event)
if (!session.user) {
throw createError({ statusCode: 401, message: 'Unauthorized' })
}
return handler(event, session.user)
})
}
Usage in endpoints: Protected routes become single-line declarations:
// server/api/app/ping.ts
export default defineSecureHandler((event, user) => {
return { message: `Hello ${user.name}` }
})
Connections
- mastering-vue-3-composables-style-guide - Applies the same DRY principle of extracting reusable logic, but for server-side utilities instead of frontend composables
- 12-design-patterns-in-vue - The "Thin Composables" pattern mirrors this approach: separate the validation layer from business logic for better testability