nuxt-auth-utils icon indicating copy to clipboard operation
nuxt-auth-utils copied to clipboard

Documentation about middleware to protect unauthorised viewing

Open pvlastaridis opened this issue 10 months ago • 6 comments

Would like some documentation about how to create a middleware to protect them from unauthorised viewing

pvlastaridis avatar Mar 06 '25 09:03 pvlastaridis

nuxt-auth-utils does not provide such functionality like other modules do. What I suggest is to create your own middleware using defineNuxtRouteMiddleware and use loggedIn property from useUserSession()

Something like so:

export default defineNuxtRouteMiddleware((to, from) => {
  const { loggedIn, user } = useUserSession();

  if (!loggedIn) {
    return abortNavigation()
  }
});

dkdev030 avatar Mar 19 '25 22:03 dkdev030

Thank you for your reply I have already done. I am just proposing to add an example to documentation.

pvlastaridis avatar Mar 20 '25 02:03 pvlastaridis

I agree that document would be helpful - and a bare bones example.

Reason: I'm hitting a barrier with the module wherein the middleware and setUserSession and useUserSession all work as documented in dev. But in production, the middleware is executed before useUserSession has value.

DavidSabine avatar Apr 03 '25 15:04 DavidSabine

nuxt-auth-utils does not provide such functionality like other modules do. What I suggest is to create your own middleware using defineNuxtRouteMiddleware and use loggedIn property from useUserSession()

Something like so:

export default defineNuxtRouteMiddleware((to, from) => { const { loggedIn, user } = useUserSession();

if (!loggedIn) { return abortNavigation() } });

I just tested with two browsers having one loggedin user be deleted by the other. The deleted user session remains valid with such middleware as loggedIn doesn't check with the server for the validity of the session.

To have a validated session, I do this :

// middleware/auth
export default defineNuxtRouteMiddleware(async() => {
    const { loggedIn } = useUserSession()
  
    if (!loggedIn.value) return navigateTo('/')

    const requestFetch = useRequestFetch()
    try {
      await requestFetch('/api/me')
    } catch(err) {
      return navigateTo('/')
    }
  })
// /api/me
export default defineEventHandler(async(event) => {
    await requireUserSession(event)
    const session = await getUserSession(event)

    if(session.user) {
        const matchUser = await useDrizzle().select().from(tables.users).where(eq(tables.users.id, session.user.id))
        if (!matchUser.length) {
            await clearUserSession(event)
            throw createError({
                statusCode: 401,
                statusMessage: 'Unauthorized'
            })
        }
    }
})

rktmatt avatar May 19 '25 14:05 rktmatt

nuxt-auth-utils does not provide such functionality like other modules do. What I suggest is to create your own middleware using defineNuxtRouteMiddleware and use loggedIn property from useUserSession() Something like so: export default defineNuxtRouteMiddleware((to, from) => { const { loggedIn, user } = useUserSession(); if (!loggedIn) { return abortNavigation() } });

I just tested with two browsers having one loggedin user be deleted by the other. The deleted user session remains valid with such middleware as loggedIn doesn't check with the server for the validity of the session.

To have a validated session, I do this :

// middleware/auth export default defineNuxtRouteMiddleware(async() => { const { loggedIn } = useUserSession()

if (!loggedIn.value) return navigateTo('/')

const requestFetch = useRequestFetch()
try {
  await requestFetch('/api/me')
} catch(err) {
  return navigateTo('/')
}

})

// /api/me export default defineEventHandler(async(event) => { await requireUserSession(event) const session = await getUserSession(event)

if(session.user) {
    const matchUser = await useDrizzle().select().from(tables.users).where(eq(tables.users.id, session.user.id))
    if (!matchUser.length) {
        await clearUserSession(event)
        throw createError({
            statusCode: 401,
            statusMessage: 'Unauthorized'
        })
    }
}

})

Nice catch! It works well, however, I can see this as a bottleneck in terms of performance, as a database query will be called on every page that uses this middleware.

I think this is an edge case (I don't think an average user will perform such an action of deleting their account in one browser but using it on another). An interesting edge case.

I propose calling the await clearUserSession() in the function call/endpoint of deleting a user account. What do you think @rktmatt ?

nizasichi avatar May 26 '25 17:05 nizasichi

@devniza the idea is that with the session persistence. If an admin decides to delete an account, the session on the device of the user stays valid until its expiration.

rktmatt avatar May 27 '25 03:05 rktmatt