New at nuxt.. and frontend as a whole.
Hi.... Ive been beating my head with nuxt for 2 weeks, I find the documentation very hard to understand.
I am trying to connect my backend with my frontend.I am using sidebase and authjs.. So far ive managed to make an authorized login, but im having a lot of trouble with fetching data with authentication and setting a useState global variable.Basically i want to login, get a jwt token and set a part of the user's data -"usertype" to a global variable because that one changes my layouts and what can the user see on a page. And I want to request data that required authentication.. send my jwt token from my cookies to the backend, fetch the data and show it on my nuxt frontend.
Also I am facing troubles with a vuetify button whichs @click doesnt work..i tried .native and many other ways still not working.
30 Replies
for Button and fetching data I attached screenshots. And for useState i did it with a composable that I deleted because nothing worked and the composable did other errors... The console.log I sent is the headers Im sending and they dont have a JWT token but some kind of next-auth.session-token that my backend cant decode because its using some kind of algo I dont know... which is weird because with login I send a jwt token with an HS256 algo and with every request to view the info my backend accepts an authentication jwt token decoded by same algo... but its not within the headers...the built in getcookie and headers from nuxt have something else entirely and im confused at this point.
Maybe when i get the jwt token in the frontend im missing a step where i need to set it in the headers or something, I dont know please help.
Also I want to set the info im getting as state with useState, so I can use it throughout the application and not request the information every time.
Which auth type the client uses for sidebase?
authjs
, local
, refresh
?authjs
since we want to introduce other signin options also eventually.
so the token doesn't persist in the headers object? or the issue is decoding it?
In the screenshots I have attached the process.Basically I set a JWT token with login... and when I send headers from the frontend to make an authenticated request.Inside I have some ext-auth.session-token not the jwt. I tried to simply fetch that token and decode it since it looks like a JWT one, but backend told me its using some kind of other algo
What that makes me think is Im missing a step with setting the jwt token in the frontend or something.
but since only logged in users can navigate the pages because Ive configured it like that I assumed the JWT token is automatically attached ... As I mentioned Im very very new at frontend
just return it instead of returning
true
next-auth can handle that automatically since we return the token from the authorize function.
- let's take in mind that, nuxt-auth will always authenticate users until we set a guard utilizing the callbacks
https://next-auth.js.org/configuration/callbacks
Callbacks | NextAuth.js
Callbacks are asynchronous functions you can use to control what happens when an action is performed.
since this part doesn't look clear in the documentation, I will try a quick POC for illustrating this further
Thank you so much... ill read it now anyway.
StackBlitz is not helping me at the moment ๐
in the mean time you can do the following:
I can also suggest the
local
strategy instead, you can use it too with other providers. here is a POC I created recently:
https://github.com/sniperadmin/poc-universal-nuxt/tree/feat/auth-uiGitHub
GitHub - sniperadmin/poc-universal-nuxt at feat/auth-ui
A universal nuxt 3 template with authentication system, component system, documentation and may be multi-tenancy (or anything you like :D) - GitHub - sniperadmin/poc-universal-nuxt at feat/auth-ui
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
// if you return the user or token, it will be in the user argument
console.log(user)
if (user.token) {
// validate the token here via request to backend
const res = await fetch('/some/route', {
method: 'POST',
body: { token: user.token }
})
if (res.ok) {
// token is valid, permit login
return true
}
}
return false
}
}
so i just put this code here pages/api/auth/[...nextauth].js ?
Isnt that what it does anyway the signIn? isnt it built in? I already managed to do the authorization with NuxtAuthHandler.. its the authentication that im having trouble with
if we will use a backendless provider such as Firebase, the approach here will be a bit tricky
- We can authenticate the user on the client using the SDK composables
- Then, verify the token on
server/api/auth/login
I already have a DRF backend and my senior wants to do it with authjs and providers ๐
the callback was designed to let the developer control when to permit the sign in , It is kinda tricky to get along with in the beginning
no worries, it is achievable though ๐
by default, from nuxt-auth perspective, once you submit the form, and no logic in the signIn callback, this user will be assumed to be authenticated
once we specify more restrictions in the
signIn
callback, now if the password is wrong, it will block loginok I can make it return the token.. but how can i set that token in my headers so i can make requests like const headers = useRequestHeaders(['cookie']) as HeadersInit
console.log("headers is", headers);
const { data: usertype } = await useFetch('http://localhost:8000/api/authuser', { headers })
console.log("data is", usertype); and they work ?
And the other battle... to put it in state
it handles it automatically
so just make it return the token
ill try right now
correct, just return token or user object, then capture token, validate in the
signin
call back and you should be good to go
Stuck ๐ or all good?very very stuck... conviced my senior to try local ๐
HAhahahaha! ๐
Local would save much time and effort
looks like it :D... i just redid the backend and im starting on the frontend , doing the nuxt.config now, if i face any trouble ill write ok ?
yep, feel free to check my example here:
https://github.com/sniperadmin/poc-universal-nuxt/tree/feat/auth-ui
but it is using Firebase, the concept will be understandable:
in
server/api/login.post.ts
for your case, just authenticate your user as normal REST requests, once you get the token, return thatGitHub
GitHub - sniperadmin/poc-universal-nuxt at feat/auth-ui
A universal nuxt 3 template with authentication system, component system, documentation and may be multi-tenancy (or anything you like :D) - GitHub - sniperadmin/poc-universal-nuxt at feat/auth-ui
thank you
worked?
hello
so far i have this login page
<template>
<div class="d-flex align-center justify-center" style="height: 100vh">
<v-sheet width="400" class="mx-auto">
<v-form fast-fail @submit.prevent="loginHandle">
<v-text-field v-model="cred.username" label="User Name"></v-text-field>
<v-text-field type='password' v-model="cred.password" label="Password"></v-text-field>
<v-btn type="submit" color="primary" block class="mt-2">Login</v-btn>
</v-form>
<div class="mt-2">
<p class="text-body-2">Don't have an account? <a href="/register">Sign Up</a></p>
</div>
</v-sheet>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
const { signIn, status, getSession } = useAuth()
console.log('status is', status.value)
definePageMeta({
auth: {
unauthenticatedOnly: true,
navigateAuthenticatedTo: '/',
},
})
const cred = reactive({
username: undefined,
password: undefined
})
async function loginHandle() {
signIn(cred);
}
</script>
import { createError, eventHandler, readBody } from 'h3';
import { z } from 'zod';
import { sign } from 'jsonwebtoken';
const refreshTokens: Record<number, Record<string, any>> = {};
export const SECRET = 'ibasimamata';
export default eventHandler(async (event) => {
const body = await readBody(event);
const result = z.object({ username: z.string().min(1), password: z.string().min(1) }).safeParse(body) if (!result.success) { throw createError({ statusCode: 400, statusMessage: 'Bad Request' }) }
const { username, password } = result.data;
try { const loginResponse = await fetch('http://localhost:8000/api/login/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) });
if (!loginResponse.ok) { throw createError({ statusCode: loginResponse.status, statusMessage: loginResponse.statusText }); }
const { access, refresh, user, user_type } = await loginResponse.json();
const expiresIn = 30; const accessToken = sign({ ...user, scope: ['test', 'user'] }, SECRET, { expiresIn });
refreshTokens[refresh] = { accessToken: accessToken, user: user };
console.log('Access Token:', accessToken); console.log('Refresh Token:', refresh); console.log('user:', user); console.log('user_type:', user_type); setCookie(event, 'jwt', accessToken ) setCookie(event, 'refresh', refresh ) return accessToken; } catch (error) { throw createError({ statusCode: 500, statusMessage: 'Internal Server Error' }); } }); and this login post i have succesfully set the tokens as cookies... but i dont know how to make the status authenticated like it happends with the nuxt auth handler... now when i login i get everything but it stays on the login page and the console gives me ncaught (in promise) Error: Invalid reference token: token at jsonPointerGet (helpers.mjs?v=79dfd484:33:13) at signIn (useAuth.mjs?v=79dfd484:23:26) login.vue:22 status is unauthenticated so I am still unauthenticated
const result = z.object({ username: z.string().min(1), password: z.string().min(1) }).safeParse(body) if (!result.success) { throw createError({ statusCode: 400, statusMessage: 'Bad Request' }) }
const { username, password } = result.data;
try { const loginResponse = await fetch('http://localhost:8000/api/login/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) });
if (!loginResponse.ok) { throw createError({ statusCode: loginResponse.status, statusMessage: loginResponse.statusText }); }
const { access, refresh, user, user_type } = await loginResponse.json();
const expiresIn = 30; const accessToken = sign({ ...user, scope: ['test', 'user'] }, SECRET, { expiresIn });
refreshTokens[refresh] = { accessToken: accessToken, user: user };
console.log('Access Token:', accessToken); console.log('Refresh Token:', refresh); console.log('user:', user); console.log('user_type:', user_type); setCookie(event, 'jwt', accessToken ) setCookie(event, 'refresh', refresh ) return accessToken; } catch (error) { throw createError({ statusCode: 500, statusMessage: 'Internal Server Error' }); } }); and this login post i have succesfully set the tokens as cookies... but i dont know how to make the status authenticated like it happends with the nuxt auth handler... now when i login i get everything but it stays on the login page and the console gives me ncaught (in promise) Error: Invalid reference token: token at jsonPointerGet (helpers.mjs?v=79dfd484:33:13) at signIn (useAuth.mjs?v=79dfd484:23:26) login.vue:22 status is unauthenticated so I am still unauthenticated
Here is the playgorund
local
example: https://github.com/sidebase/nuxt-auth/tree/main/playground-local
in the server endpoint of login, all you need to do is to get the token from your backend and return it.
usually the format look like this:
If you would like to check the authenticated status, you can use the status
composable for that:
once the token is returned in the proposed format, nuxt auth captures it and stores the session in a session
composableGitHub
nuxt-auth/playground-local at main ยท sidebase/nuxt-auth
๐ Nuxt user authentication and sessions via authjs (next-auth), local and refresh providers. nuxt-auth wraps NextAuth.js to offer the reliability & convenience of a 12k star library to the ...
thank you , just returned from holidays ill try it