Learn Nuxt - Security & Authentication
Series/Learn Nuxt/Episode 12
Episode 12 of 24

Learn Nuxt - Security & Authentication

This episode covers security and authentication in Nuxt: using @sidebase/nuxt-auth for login and sessions, secure cookie management, protecting routes with middleware, and Role-Based Access Control and secure data fetching.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Once an application has data and forms, security is no longer optional. Episode 12 covers authentication and security in Nuxt: how users sign in, how sessions are stored securely, how routes are protected, and how access rights differ between roles.

We'll cover two approaches: the complete @sidebase/nuxt-auth, and building a lighter custom authentication. Both are valid — the choice depends on your project's needs. What's non-negotiable: secure cookies, protective middleware, and authorization checked on the server.

Authentication with @sidebase/nuxt-auth

Installation and Configuration

@sidebase/nuxt-auth wraps Auth.js so login, sessions, and callbacks are available quickly:

Install nuxt-auth
npm install @sidebase/nuxt-auth
JSKonfigurasi nuxt-auth
export default defineNuxtConfig({
  modules: ["@sidebase/nuxt-auth"],
  auth: {
    provider: {
      type: "local",
      endpoints: {
        signIn: { path: "/api/auth/login", method: "post" },
        signOut: { path: "/api/auth/logout", method: "post" },
      },
    },
  },
})

The configuration above points login to an API endpoint you provide. This module provides useSession in components as well as middleware endpoints to protect server routes.

Login and Logout in Components

JSLogin dan logout
import { signIn, signOut } from "#auth"
 
async function login() {
  await signIn({ username: form.username, password: form.password })
}
 
async function keluar() {
  await signOut()
}

signIn and signOut from #auth handle the entire session flow. After a successful login, useSession() in other components immediately reflects the user status.

Custom Auth as an Alternative

Tailored to Your Own Needs

If the project needs full control — for example, integration with an internal SSO system — custom authentication makes more sense. The principles stay the same: verify credentials on the server, create a session token, store it in a secure cookie.

Your Own Login Endpoint

JSserver/api/auth/login.post.ts
export default defineEventHandler(async (event) => {
  const { username, password } = await readBody(event)
 
  if (!verifikasiKredensial(username, password)) {
    throw createError({ statusCode: 401, message: "Kredensial salah" })
  }
 
  const token = buatTokenSesi(username)
  setCookie(event, "session", token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    maxAge: 60 * 60 * 24,
  })
 
  return { ok: true }
})

setCookie(event, "session", token, {...}) stores the token in a cookie. The httpOnly attribute prevents access via JavaScript, secure ensures it's only sent over HTTPS, and sameSite prevents CSRF attacks.

Session Handling and Secure Cookies

Three mandatory attributes for session cookies:

  • httpOnly: JavaScript in the browser can't read the cookie, reducing XSS risk.
  • secure: the cookie is only sent over HTTPS.
  • sameSite: restricts cross-site cookie sending, blocking CSRF.
JSMembaca dan menghapus session
const token = getCookie(event, "session")
if (!token) {
  throw createError({ statusCode: 401, message: "Belum login" })
}
 
async function logout(event) {
  deleteCookie(event, "session")
}

getCookie(event, "session") reads the cookie on the server, and deleteCookie removes it on logout. Validating the token on every sensitive request is a must.

Checking in Server Routes

Don't rely on components alone for security. Every sensitive server route must check the session:

JSProtect server route
export default defineEventHandler((event) => {
  if (!getCookie(event, "session")) {
    throw createError({ statusCode: 401, message: "Akses ditolak" })
  }
  return { data: "hanya untuk yang login" }
})

Protecting Routes with Middleware

Auth Middleware for Pages

Combine the middleware from episode 4 with the session cookie:

JSapp/middleware/auth.ts
export default defineRouteMiddleware(() => {
  if (!useCookie("session").value) {
    return navigateTo("/login")
  }
})

useCookie("session") reads the token on the client. Pages that register this middleware automatically redirect logged-out users to the login page.

Role-Based Access Control and Secure Data Fetching

Roles and Permissions

Role-Based Access Control differentiates access rights based on the user's role:

JSCek peran pengguna
export default defineEventHandler((event) => {
  const pengguna = getPenggunaDariSesi(event)
 
  if (pengguna.peran !== "admin") {
    throw createError({
      statusCode: 403,
      message: "Butuh hak admin",
    })
  }
 
  return listSemuaPesanan()
})

Role checks must always happen on the server, not just by hiding buttons in the UI. Status 403 is returned when a user is logged in but lacks permission.

Data That Never Leaks

Secure data fetching means: a server route only returns data the user is actually allowed to see. Filter by identity from the session, don't return the entire database.

Conclusion

Episode 12 layers your application with security: authentication with @sidebase/nuxt-auth or custom auth, sessions stored in httpOnly and secure cookies, page routes protected by middleware, and Role-Based Access Control always rechecked on the server.

Key takeaways:

  • @sidebase/nuxt-auth provides quick login, session, and logout.
  • Custom authentication fits when you need full control over the login flow.
  • Session cookies must use httpOnly, secure, and sameSite.
  • Middleware protects pages; also check sessions in server routes.
  • Role authorization must be validated on the server, not only in the UI.
  • Server routes only return data the user is allowed to see.

In the next episode, episode 13, we will discuss API integration and data protection — consuming external APIs from Nuxt, protecting requests with auth headers, handling secrets safely, and rate limiting and error handling for resilient integrations.

Learn Nuxt - Security & Authentication | Learn Nuxt