N
Nuxt9mo ago
VVadim

auth cookie

How can I authenticate my nuxt3 app against spring boot 3 app, java app uses JSESSIONID cookie to track sessions. I need to authenticate and then somehow include this cookie to all subsequent requests + protect pages with midleware.
4 Replies
Gugustinette
Gugustinette9mo ago
You'll probably be interested in the useCookie composable : https://nuxt.com/docs/api/composables/use-cookie Pretty good, but this will require you to write some middleware in your nuxt app to handle it correctly (redirection and more). From my experience, this is a bit harsh to configure (as their is still no magic nuxt-auth module for Nuxt3). Here is the kind of middleware I used. But things can change depending on how you are rendering your pages, what type of cookie you use,...
// middleware/auth.global.ts
const userAuthenticated = (accessToken: string | null | undefined) => {
return accessToken !== undefined && accessToken !== null;
};

/**
* Auth middleware
*/
export default defineNuxtRouteMiddleware((to) => {
// Skip this middleware on the client, as we are using an httpOnly cookie for authentication
if (process.client) return;

// Get the access token from the cookie
const accessToken = useCookie('accessToken');

// If the user tries to access any route (except /login) and is not authenticated
if (
to.path !== '/login' &&
!userAuthenticated(accessToken.value)
) {
// Redirect to /login
return navigateTo('/login');
}

// If the user tries to access /login and is authenticated
if (
to.path === '/login' &&
userAuthenticated(accessToken.value)
) {
// Redirect to /
return navigateTo('/');
}

// If the user is authenticated, allow the request to continue
return;
});
// middleware/auth.global.ts
const userAuthenticated = (accessToken: string | null | undefined) => {
return accessToken !== undefined && accessToken !== null;
};

/**
* Auth middleware
*/
export default defineNuxtRouteMiddleware((to) => {
// Skip this middleware on the client, as we are using an httpOnly cookie for authentication
if (process.client) return;

// Get the access token from the cookie
const accessToken = useCookie('accessToken');

// If the user tries to access any route (except /login) and is not authenticated
if (
to.path !== '/login' &&
!userAuthenticated(accessToken.value)
) {
// Redirect to /login
return navigateTo('/login');
}

// If the user tries to access /login and is authenticated
if (
to.path === '/login' &&
userAuthenticated(accessToken.value)
) {
// Redirect to /
return navigateTo('/');
}

// If the user is authenticated, allow the request to continue
return;
});
Also here is how my Nuxt App is defining the cookie in the API (I use Nuxt as a backend) :
// /server/api/auth/login.ts
import { CryptoUtil } from 'crypto-util';
import { UserSchema } from '~/server/model/user.schema';

/**
* Test route
*/
export default defineEventHandler(async (event) => {
// Get the request body
const body = await readBody(event);

// Try to find the user with the given credentials
const user = await UserSchema.findOne({
email: body.email,
password: body.password,
});

// If the user is not found, throw an error
if (!user) {
throw createError({
statusCode: 404,
statusMessage: 'User not found',
});
}

// Generate a new access token
const accessToken = CryptoUtil.generateRandomString(256);

// Set the access token in the user
user.accessToken = accessToken;
await user.save();

// Set the access token in a httpOnly cookie for the client
setCookie(event, 'accessToken', accessToken, {
secure: true,
httpOnly: true,
sameSite: 'strict',
// Expires in 1 year
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7 * 365),
});

// Redirect the user to the dashboard
return sendRedirect(event, '/');
});
// /server/api/auth/login.ts
import { CryptoUtil } from 'crypto-util';
import { UserSchema } from '~/server/model/user.schema';

/**
* Test route
*/
export default defineEventHandler(async (event) => {
// Get the request body
const body = await readBody(event);

// Try to find the user with the given credentials
const user = await UserSchema.findOne({
email: body.email,
password: body.password,
});

// If the user is not found, throw an error
if (!user) {
throw createError({
statusCode: 404,
statusMessage: 'User not found',
});
}

// Generate a new access token
const accessToken = CryptoUtil.generateRandomString(256);

// Set the access token in the user
user.accessToken = accessToken;
await user.save();

// Set the access token in a httpOnly cookie for the client
setCookie(event, 'accessToken', accessToken, {
secure: true,
httpOnly: true,
sameSite: 'strict',
// Expires in 1 year
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7 * 365),
});

// Redirect the user to the dashboard
return sendRedirect(event, '/');
});
This is some Nuxt gymnastic to learn at the moment, but the in coming nuxt-auth official package will probably do some incredible black magic and cool DX. It should be released this year I think.
silvesterwali
silvesterwali9mo ago
https://gist.github.com/silvesterwali/4c4a415e9e76dc666bb01cbaf510d082 here is my composable maybe will help you if you not working with server at all.
Gist
Composable for Nuxt3 for handle simple auth
Composable for Nuxt3 for handle simple auth . GitHub Gist: instantly share code, notes, and snippets.
VVadim
VVadimOP9mo ago
Thank you. I will try to apply a similar approach in my project. I really hope that the Nuxt team will make nuxt-auth as soon as possible.
Gugustinette
Gugustinette9mo ago
Yup, this is clearly something missing for a lot of people (that's why it is pretty much the next official module on the roadmap)
Want results from more Discord servers?
Add your server