N
Nuxt2w ago
Yuri

JWT generation

Hello. I create an e-commerce project. I want to use JWT (access & refresh) for everybody (guests & users). Also I want to use /server/api. I create plugins/api.ts for custom fetch. I guess to create /server/api/token/get & /server/api/token/refresh/ for working with tokens. My questions: 1. Where do I need first request to token/get for getting the token pair? 2. When the page loads I need to check "Does the cookie refreshToken exist?" If YES I need to fetch /token/refresh/. Where do I need to do it? Maybe is there some ready solution?
2 Replies
kapa.ai
kapa.ai2w ago
Hi @Yuri. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the knowledge sources provided, I can offer some guidance on implementing JWT authentication in a Nuxt 3 project, though there isn't a complete ready-made solution presented in the given information. Here's how you can approach your questions: 1. For the first request to token/get to obtain the initial token pair: You can make this request in a Nuxt plugin that runs on both client and server side. This ensures that the tokens are obtained as early as possible in the application lifecycle. 2. Checking for the existence of the refreshToken cookie and refreshing it: This can be done in a plugin or middleware. Here's an example of how you might implement this in a custom fetch composable:
// @/composables/useCustomFetch.ts
import type { UseFetchOptions } from 'nuxt/app'
import { defu } from 'defu'

export function useCustomFetch<T> (url: string, options: UseFetchOptions<T> = {}) {
const config = useRuntimeConfig()
const { isSignedIn, getToken, setToken } = useAuthStore()

const defaults: UseFetchOptions<T> = {
baseURL: config.public.apiBaseUrl,
key: url,
server: false,
retry: 1,
retryStatusCodes: [401],

onRequest({ options }) {
options.headers = isSignedIn
? { Authorization: `Bearer ${getToken()}` }
: {}
},

async onResponseError({ response, options }) {
if (response.status === 401) {
await useFetch('/auth/refresh', {
baseURL: config.public.apiBaseUrl,
method: 'POST',
server: false,
credentials: 'include',

onResponse({ response }) {
setToken(response._data.token)
},
})
}
}
}

const params = defu(options, defaults)

return useFetch(url, params)
}
// @/composables/useCustomFetch.ts
import type { UseFetchOptions } from 'nuxt/app'
import { defu } from 'defu'

export function useCustomFetch<T> (url: string, options: UseFetchOptions<T> = {}) {
const config = useRuntimeConfig()
const { isSignedIn, getToken, setToken } = useAuthStore()

const defaults: UseFetchOptions<T> = {
baseURL: config.public.apiBaseUrl,
key: url,
server: false,
retry: 1,
retryStatusCodes: [401],

onRequest({ options }) {
options.headers = isSignedIn
? { Authorization: `Bearer ${getToken()}` }
: {}
},

async onResponseError({ response, options }) {
if (response.status === 401) {
await useFetch('/auth/refresh', {
baseURL: config.public.apiBaseUrl,
method: 'POST',
server: false,
credentials: 'include',

onResponse({ response }) {
setToken(response._data.token)
},
})
}
}
}

const params = defu(options, defaults)

return useFetch(url, params)
}
This custom fetch composable checks for a 401 status (which typically indicates an expired token) and automatically attempts to refresh the token using the /auth/refresh endpoint. Stack Overflow - How to reinitiate/resend a request with $fetch like Axios? (https://stackoverflow.com/questions/77270727) For handling cookies, you can use the useCookie composable in Nuxt 3. Here's an example of how you might use it to refresh a cookie value:
<script setup lang="ts">
const tokenCookie = useCookie('token')

const login = async (username, password) => {
const token = await $fetch('/api/token', { ... }) // Sets `token` cookie on response
refreshCookie('token')
}

const loggedIn = computed(() => !!tokenCookie.value)
</script>
<script setup lang="ts">
const tokenCookie = useCookie('token')

const login = async (username, password) => {
const token = await $fetch('/api/token', { ... }) // Sets `token` cookie on response
refreshCookie('token')
}

const loggedIn = computed(() => !!tokenCookie.value)
</script>
Nuxt Docs - refreshCookie (https://nuxt.com/docs/api/utils/refresh-cookie) Remember to handle both client-side and server-side scenarios. For server-side operations, you might need to use the event object to access and set cookies:
const event = useRequestEvent();

const res = await $fetch<{ accessToken: string }>('/api/auth/refresh', {
method: 'POST',
headers: useRequestHeaders(['cookie']),
onResponse({ response }) {
const cookies = response.headers.getSetCookie();

if (cookies.length) {
cookies.forEach((cookie) => {
if (event) {
appendResponseHeader(event, 'set-cookie', cookie);
}
});
}
},
});
const event = useRequestEvent();

const res = await $fetch<{ accessToken: string }>('/api/auth/refresh', {
method: 'POST',
headers: useRequestHeaders(['cookie']),
onResponse({ response }) {
const cookies = response.headers.getSetCookie();

if (cookies.length) {
cookies.forEach((cookie) => {
if (event) {
appendResponseHeader(event, 'set-cookie', cookie);
}
});
}
},
});
Stack Overflow - Nuxt3 server setCookie - cookie value does not change, what could be problem? (https://stackoverflow.com/questions/78605772) These examples should give you a starting point for implementing JWT authentication in your Nuxt 3 project. However, please note that a complete authentication system involves more components and security considerations that are beyond the scope of the provided knowledge sources. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@740173469404364872> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?