N
Nuxt3mo ago
felix

Auth cookie being refreshed during SSR

Hi everyone! Im running into an issue where Cookies that are refreshed during SSR isnt used in subsequent SSR fetch requests. Our setup is a bit weird but we have a Nuxt frontend that is being SSR'd. All requests are passed through a useFetch wrapped to set a refreshToken timeout. We have a Nitro instance running that proxy all our request to our other Docker C# API. We have solved the issue where the cookie is refreshed when the server is making a SSR fetch, we just pass it to the frontend with the useCookie composable, the issue we are running into now is that after the first SSR fetch request to our C# API refreshes the token, we update the client cookie with useCookie but subsequent request done that SSR request arent using the updated token but instead using the old invalidated token. We could solve this by making the old token valid some time after it gets refreshed but I wanted to check if anyone here have any better ideas. Thanks!
4 Replies
Mediv0
Mediv03mo ago
I've been stuck on this issue for five days and tried every possible solution. While my approach might not be the best, it works. I fixed the issue by using middleware combined with a timestamp to track the JWT token's expiry date. In my case, the token was set to expire after 20 minutes. In the middleware, I check if the token has expired, and if so, I handle the refresh, pass the updated cookies, and continue with the request. also have a custom useAuth composable with a useState inside to keep track of cookie expiry on the client side. Additionally, I use a Redis instance on the backend to cache both the JWT and the refresh token for one minute. This ensures that if any subsequent requests fail to get the cookie from the frontend, I can return it directly from the cache. instead of generating new one ( in my case i revoke previous refresh tokens ) simplfied version
import { setHeader } from "h3";
import { useAuth } from "~/composable/useAuth";

export default defineNuxtRouteMiddleware(async () => {
const { isRefreshNeeded, refreshCSR, refreshSSR, setCookieCSR } = useAuth();

if (import.meta.server) {
if (isRefreshNeeded()) {
try {
const { cookies, exp } = await refreshSSR(useRequestHeaders());

cookies.push(`exp=${exp}; Path=/`);
setHeader(useRequestEvent()!, "set-cookie", cookies);

return true;
}
catch {
return navigateTo("/auth/login");
}
}
}

if (import.meta.client) {
if (isRefreshNeeded()) {
try {
await refreshCSR(useRequestHeaders());
setCookieCSR();
return true;
}
catch {
return navigateTo("/auth/login");
}
}
}
});
import { setHeader } from "h3";
import { useAuth } from "~/composable/useAuth";

export default defineNuxtRouteMiddleware(async () => {
const { isRefreshNeeded, refreshCSR, refreshSSR, setCookieCSR } = useAuth();

if (import.meta.server) {
if (isRefreshNeeded()) {
try {
const { cookies, exp } = await refreshSSR(useRequestHeaders());

cookies.push(`exp=${exp}; Path=/`);
setHeader(useRequestEvent()!, "set-cookie", cookies);

return true;
}
catch {
return navigateTo("/auth/login");
}
}
}

if (import.meta.client) {
if (isRefreshNeeded()) {
try {
await refreshCSR(useRequestHeaders());
setCookieCSR();
return true;
}
catch {
return navigateTo("/auth/login");
}
}
}
});
and in my custom useFetch if i ecounter a 401 i just redirect to the login page because at this point if you hit 401 it means something is wrong
felix
felixOP3mo ago
This is a great idea but we solved it another way. We just changed the API to not auto refresh the token. But I think the underlying issue here is still annoying. We used this principal to pass headers from fetches called from our Client SSR request https://nuxt.com/docs/getting-started/data-fetching#passing-headers-and-cookies While it worked to refresh cookies for the client when Nuxt renders the Client SSR it will do internal fetches to resolve your useAsyncData calls it will not use the updated credentials but instead to old ones. Im going to open an Issue about this aswell 🙂 Here is a better explaination of what we used before: https://github.com/nuxt/nuxt/issues/13096#issuecomment-1397311005
GitHub
pass on cookies from server-side API calls on SSR response · Issue ...
Environment Operating System: Linux Node Version: v16.13.1 Nuxt Version: 3.0.0-27333874.279bfdc Package Manager: [email protected] Bundler: Vite User Config: - Runtime Modules: - Build Modules: - Reprod...
Nuxt
Data fetching · Get Started with Nuxt
Nuxt provides composables to handle data fetching within your application.
Mediv0
Mediv03mo ago
It's really frustrating because this issue could easily be resolved if they allow to preserve the headers for subsequent requests.
felix
felixOP2mo ago
Yeah I agree, but there could be security reasons Might want to open an issue about it. Daniel is active on GitHub
Want results from more Discord servers?
Add your server