HTTP-only Cookie vs Store-based Auth With Nuxt 3 Route Middleware

181 Views Asked by At

I'm poking around with Nuxt.js and fiddling about with authentication. In the past, I've used mostly session-based authentication, so much of this is quite new to me. Thanks in advance!

What I'd like to know is:

  1. Are there any disadvantages to using HTTP-only cookie-based authentication instead of store-based authentication?
  2. Is my approach below sound? (using Nuxt 3 global Middleware; i.e. auth.global.ts)

Summary of what I'm trying to do:

  • Set an HTTP only cookie upon login
  • Use global middleware to check authentication via fetch
  • Validate the cookie by querying my database (Prisma, Postgresql)

My route middleware:

    // middleware/auth.global.js

    export default defineNuxtRouteMiddleware(async (to, from) => {

        let isAuthenticated = false;

        if (process.server) {
            const apiBaseUrl = process.env.API_BASE_URL;
            const headers = useRequestHeaders(['cookie'])
            const { data } = await useFetch(`${apiBaseUrl}/api/auth/status`, { headers })
        
            if (data.value && data.value.authenticated) {
                isAuthenticated = true;
            }
        
            // // Redirect to login page if not logged in
            if (!isAuthenticated && to.path !== '/login') {
                return navigateTo('/login');
            }
        }

    });

My server API route:

    // server/api/auth/status.ts

    import { PrismaClient } from '@prisma/client';
    import jwt from 'jsonwebtoken';

    const prisma = new PrismaClient();

    export default defineEventHandler(async (event) => {
        try {
            const cookieHeader = event.req.headers.cookie;
            const token = cookieHeader?.split('; ').find(row => row.startsWith('token='))?.split('=')[1];

            if (!token) {
                return { authenticated: false };
            }

            const jwtSecret = process.env.JWT_SECRET;
            const decodedToken = jwt.verify(token, jwtSecret);
            const userId = decodedToken.userId;
            const user = await prisma.user.findUnique({
                where: {
                    id: userId,
                },
            });

            return { authenticated: true };

        } catch (error) {

            return { authenticated: false };

        }
    });
0

There are 0 best solutions below