Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify and enrich session on server-side #203

Open
tobiasdiez opened this issue Oct 3, 2024 · 5 comments
Open

Verify and enrich session on server-side #203

tobiasdiez opened this issue Oct 3, 2024 · 5 comments
Labels
question Further information is requested

Comments

@tobiasdiez
Copy link

Often one needs to check if a session is still valid on the server-side. For example, one may want to present the user with an option to logout on all devices, which then should invalidate all existing sessions.

For this, one needs to query for every request the a sever-side session storage (and perhaps update it). Currently, this is relatively hard to implement. A few suggestions to make this easier:

  1. Implement a useRawSession method to directly access the h3 session (in other words make
    function _useSession(event: H3Event, config: Partial<SessionConfig> = {}) {
    public) - alternatively, add the sessionId to the public interface of UserSession
  2. Implement a server middleware that calls a hook where devs can check the validity of the sessionId (and update timestamps like "last active" etc)
  3. ...and perhaps return some data that one would like to associate with the current session on all server routes but don't directly store in the user cookie (e.g. permissions)

Point two and three might look like:

export default defineEventHandler(async (event) => {
  const session = await _useSession(event)
  // session.id is not a good way to check if there is a session as it will always be set by h3 (except if one calls clearSession)
  // use session.data instead, with the convention that if it is an empty object, there is no session ?
  if (session.id && Object.keys(session.data).length !== 0) {
    try {
      // Check if session is valid
      const info = await hooks.call('validateSession', {id: session.id, data: session.data})
      // Is there a better to store data in the session object?
      session.server = info
    } catch {
      // Clear session
      await session.clear()
    }
  }
})
@atinux
Copy link
Owner

atinux commented Oct 4, 2024

Did you take a look at the fetch hook (https://github.com/atinux/nuxt-auth-utils?tab=readme-ov-file#extend-session) to already implement this logic?

@tobiasdiez
Copy link
Author

Yes, I did. But this is not run on server-routes (right?) and doesn't provide the sessionId.

@atinux
Copy link
Owner

atinux commented Oct 7, 2024

What about creating a server util to wrap requireUserSession(event)?

// server/utils/session.ts
export async function requireValidUserSession(event) {
  const session = await requireUserSession(event)

  // Do your logic here or throw createError(...)
  // return the extended session
  return session
})

What we can do is to expose the session.id, or you can do you own with:

await setUserSession({ id: randomUUID(), user: { ... } })

@atinux atinux added the question Further information is requested label Oct 7, 2024
@tobiasdiez
Copy link
Author

Yes, the approach via requireValidUserSession would work as well and I'm using something like this in https://github.com/JabRef/JabRefOnline/blob/main/server/middleware/validateSession.ts. I just thought that it is a very common pattern and thus would have liked the nuxt-auth module to expose such a hook.

@atinux
Copy link
Owner

atinux commented Oct 7, 2024

it's tricky as you may want to add some local cache to avoid extending everytime based on the ID, at least you have a workaround :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants