Non solo AI nel 2026:
Cookie vs LocalStorage
Given the current landscape, imagine having just launched your new AI-powered SaaS. The UI is snappy, models respond in milliseconds (kudos!), and investors are thrilled. But while the team is celebrating, a three-line script is silently sending that single access token to an anonymous server.
No alarms ring. No firewall blocks the request. Why? Because that token was stored in LocalStorage.
This is a classic Web Security issue. If you think "sanitizing inputs" is enough to keep you safe, this article might help you understand why it's not.
Why do we still see tutorials recommending localStorage.setItem('accessToken', token)? The answer is simple: it’s incredibly convenient and fast to implement. No CORS headaches, no domain issues, it just works.
But in a Zero Trust Architecture, convenience comes at a steep price. LocalStorage has (unfortunately) a fatal design flaw regarding sensitive data: it is accessible by any JavaScript code running on your page. This includes:
If an attacker manages to execute JS on your page (XSS), reading LocalStorage is as trivial as reading a variable.
The correct solution isn't to try and "lock down" LocalStorage, but to use storage that JavaScript cannot read: HttpOnly Cookies.
When a cookie is flagged as HttpOnly, the browser hides it from the JavaScript engine (document.cookie won't show it) but continues to send it automatically with every request to the origin server. This drastically reduces the attack surface: even with an XSS vulnerability, the attacker cannot steal the token so easily.
Although Volcanic Backend natively supports various authentication modes (including classic Bearer Tokens via Header, useful for mobile apps or server-to-server calls), for Enterprise Web Apps we strictly enforce Cookie mode.
This configuration shifts persistence responsibility from the (vulnerable) client code to the (protected) browser, leveraging two fundamental barriers:
In this scenario, LocalStorage remains empty (or used only for UI preferences), and authentication flows transparently and securely.
Let's look at how to implement this pattern leveraging Nuxt 3 composables and the Nitro server engine.
In a Volcanic Backend project, cookie management happens in the controller, leveraging the Fastify-based architecture.
First, we define the route in src/api/auth/routes.ts:
// src/api/auth/routes.ts
export default {
config: {
controller: "controller",
enable: true,
tags: ["Auth"],
},
routes: [
{
method: "POST",
path: "/login",
handler: "auth.login",
config: {
description: "Secure Login with HttpOnly Cookie",
response: {
200: { type: "object", properties: { user: { type: "object" } } },
},
},
},
],
};And then implement the logic in the controller src/api/auth/controller/auth.ts:
// src/api/auth/controller/auth.ts
import { FastifyReply, FastifyRequest } from "@volcanicminds/backend";
export async function login(req: FastifyRequest, reply: FastifyReply) {
const { username, password } = req.body as any;
// ... validate user ...
// const user = await authService.validate(username, password)
const token = generateAccessToken(user.id);
// Save the token in a secure cookie
reply.setCookie("token", token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
path: "/",
maxAge: 60 * 60 * 24, // 1 day
});
// The client doesn't need to receive the token in the body!
return { success: true, user: { id: user.id, username: user.username } };
}On the frontend, we don't need to do anything with the token. We don't save it, we don't read it. When calling an API with $fetch (or useFetch), the browser will automatically attach the cookie.
// composables/useAuth.ts
export const useAuth = () => {
const user = useState("user", () => null);
const login = async (credentials: any) => {
// The response will automatically set the cookie
const data = await $fetch("/api/auth/login", {
method: "POST",
body: credentials,
});
// We only update the user state for the UI
user.value = data.user;
};
return { user, login };
};This approach ensures that the secret (the access token) is invisible to JavaScript code. Even if a malicious script tried to read document.cookie, it would find an empty string (thanks to HttpOnly). And without the token, it cannot impersonate the user outside the victim's browser.
At Volcanic Minds, we develop complex platforms (Enterprise ERP & Dashboards). For us, security isn't a feature; it's the starting point. We don't just use libraries; we design resilient architectures, which is why we built the Volcanic Backend.
An open-source framework that natively integrates these security best practices, allowing teams to focus on business logic knowing they are resting on solid foundations.
Security has always (and even more so in 2026) been about more than just HTTPS or complex passwords. It's about data architecture on the client and between client and server. Moving tokens from LocalStorage to HttpOnly Cookies is a zero-cost investment that drastically raises the bar that potential attackers must overcome.
If you have doubts about your platform's security, at Volcanic Minds we offer specific architectural audits to identify and close these gaps before it's too late.
: 17 gennaio 2026