nuxt-alt / auth

An alternative module to @nuxtjs/auth
https://nuxt-alt-auth.vercel.app/
MIT License
96 stars 20 forks source link

Checking login state → double redirect when logged in. Race condition at server? #5

Closed Arecsu closed 10 months ago

Arecsu commented 1 year ago

I've just deployed a Nuxt project to Vercel using the latest version of @nuxt-alt/auth (2.1.9)

The logic of my site is very simple: every single page is protected. When user is not logged in, it needs to be redirected to /login. Then, after successful login, it will be returned to home (/)

I've noticed something that didn't happen when developing locally: I'm logged in, but refreshing from any page will always result in the browser being redirected to /login and after a second, returning to home /.

Tried enabling and disabling globalMiddleware and the builtin middleware (enableMiddleware) in every combination, and/or relying on a global Nuxt 3 middleware.

This is the code of the middleware:

export default defineNuxtRouteMiddleware((to) => {
   const auth = useAuth()
   console.log(auth.loggedIn)

   if (!auth.loggedIn && to.path !== '/login') {
      console.log('going to login')
      return navigateTo('login')
   } else if (auth.loggedIn && to.path === '/login') {
      console.log('going to /')
      return navigateTo('/')
   }
})

Web is SSR. From what I'm able to debug, in the server console, the middleware will indeed hit "going to login" and redirect to /login because auth.loggedIn is false. In the client, however, auth.loggedIn is always true. Only after a second the server will properly check the JWT token from my auth user endpoint setup at nuxt.config.ts and then proceed to redirect the user correctly from the client.

Is there any chance to be a race condition in the server side that checks the validity of the JWT before processing the logic of redirects and middlewares? Am I doing something wrong?

This doesn't seem to happen when running the server locally, presumably because latency is super low and happens really fast to even notice.

EDIT: in local development, the server console returns auth.loggedIn = true. Hmmm

As extra info, I have a @nuxt-alt/proxy configured to point to another Vercel custom node.js app that handles the login. In local development, my nuxt project points to this Vercel login server as well. Everything seems to be working fine. Weird that not being local yields different results.


   auth: {
      globalMiddleware: false,
      enableMiddleware: false,
      strategies: {
         local: {
            token: {
               property: 'access_token',
               // global: true,
               // required: true,
               type: 'Bearer'
            },
            user: {
               property: 'content.username',
               autoFetch: true
            },
            endpoints: {
               login: { url: '/api/user/login', method: 'post' },
               user: { url: '/api/user/me', method: 'get' },
               logout: false,
            }
         }
      }
   },
   proxy: {
      enableProxy: true,
      proxies: {
         '/api': {
            target: 'https://custom-auth.vercel.app',
            changeOrigin: true,
         },

      },
   },
Arecsu commented 1 year ago

as a workaround I wrapped my middleware with if (process.client) but I don't think that's the proper way of doing it:

export default defineNuxtRouteMiddleware((to) => {

   if (process.client) {
   const auth = useAuth()
      if (!auth.loggedIn && to.path !== '/login') {
         return navigateTo('/login')
      } else if (auth.loggedIn && to.path === '/login') {
         return navigateTo('/')
      }
   }
})