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

[Bug]: validateSession returns null. Sveltekit + MongoDB + Lucia #1647

Open
EGSP opened this issue Jul 26, 2024 · 8 comments
Open

[Bug]: validateSession returns null. Sveltekit + MongoDB + Lucia #1647

EGSP opened this issue Jul 26, 2024 · 8 comments
Labels
bug Something ain't right...

Comments

@EGSP
Copy link

EGSP commented Jul 26, 2024

Package

lucia

Describe the bug

I have a cookie that stores a record of authentication. In the hook function I read the cookie and check the validity of the session using the lucia.validateSession(session_id) function. The session id written in the cookie matches the id in the Mongo database. The problem I think is that Lucia cannot find the user during validation.

My user has an identifier of type ObjectId and is named “_id”. From what I have found on the internet and neighboring issues - I assume that lucia is trying to find a user with the property “_id” whose value is equal to the string value “user_id”. And apparently the types don't match

@EGSP EGSP added the bug Something ain't right... label Jul 26, 2024
@EGSP
Copy link
Author

EGSP commented Jul 26, 2024

I have tried to specify _id type, but it does not help

declare module "lucia" {
    interface Register {
        Lucia: typeof lucia;
        UserID: ObjectId;
    }
}

interface UserDocumentScheme {
    _id: string;
}

interface SessionDocumentScheme {
    _id: string;
    user_id: string;
    expires_at: Date;
}

export function prepare_lucia() {
    const _db = get_db();

    const users = _db.collection("users") as Collection<UserDocumentScheme>;
    const sessions = _db.collection("sessions") as Collection<SessionDocumentScheme>;

    adapter = new MongodbAdapter(sessions, users);

    lucia = new Lucia(adapter,
        {
            sessionCookie: {
                attributes: {
                    secure: false
                }
            },
            sessionExpiresIn: new TimeSpan(1,"w")
        }
    );
}

@oscarhermoso
Copy link

Does something like this help, @EGSP ?

  declare module "lucia" {
      interface Register {
          Lucia: typeof lucia;
           UserID: ObjectId;
+          DatabaseUserAttributes: UserDocumentScheme;
      }
  }


interface UserDocumentScheme {
    _id: string;
+   name: string;  
}

// ...

    lucia = new Lucia(adapter,
        {
+         getUserAttributes: (attributes) => {
+            return {
+               name: attributes.name
+             };
+ 	  },
          sessionCookie: {
              attributes: {
                  secure: false
              }
          },
          sessionExpiresIn: new TimeSpan(1,"w")
        }
    );

I do not use MongoDB, but assume this work based on other open source projects that use "@lucia-auth/adapter-mongodb" on GitHub:

https://github.com/PriMacula/ecommerceTemplate/blob/e0ef494bc5d076259bb6a701aa8faea5c4740652/src/app/models/session.js#L17C14-L20

https://github.com/PriMacula/ecommerceTemplate/blob/e0ef494bc5d076259bb6a701aa8faea5c4740652/src/lib/auth.js#L7-L18

@boylett
Copy link

boylett commented Aug 11, 2024

I was able to get it working by coercing the session ID to an ObjectId during validation:

import { ObjectId } from "bson";

// Validate the session
const { session, user } = await lucia.validateSession(
  // @ts-expect-error
  new ObjectId(sessionId)
);

@C-Vane
Copy link

C-Vane commented Aug 18, 2024

I opened a PR for this could this solve the issue?
#1670

@Kingnoba
Copy link

I wrote a custom adapter extending MongodbAdapter to address the issue of using ObjectId for user lookups. It overrides the getSessionAndUser method to use ObjectId in the user lookup stage and then utilizes the $addFields stage to convert the _id back to a string for compatibility with Lucia.

I don't understand why the OG adapter doesn't do this in the first place if it insists on using strings elsewhere? I don't want to compromise indexing of users due to string id's.

@xSenny
Copy link

xSenny commented Aug 22, 2024

I was able to get it working by coercing the session ID to an ObjectId during validation:

import { ObjectId } from "bson";

// Validate the session
const { session, user } = await lucia.validateSession(
  // @ts-expect-error
  new ObjectId(sessionId)
);

Error: input must be a 24 character hex string, 12 byte Uint8Array, or an integer. What about this error? because the actual sessionId is 40 characters long

@NRProjects
Copy link

I have this working for me, no coercion needed.

const user = db.collection("users") as Collection<UserDoc>;
const session = db.collection("sessions") as Collection<SessionDoc>;

const adapter = new MongodbAdapter(session, user)

export const lucia = new Lucia(adapter, {
    sessionCookie: {
        name: "session",
        attributes: {
            secure: !dev
        }
    },

    getUserAttributes: (attributes) => {
        return {
            email: attributes.email,
        }
    },
});

declare module "lucia" {
    interface Register {
        Lucia: typeof lucia;
        DatabaseUserAttributes: User;
        UserId: ObjectId
    }
}

interface UserDoc {
    _id: ObjectId;
}

const session = await lucia.createSession(existingUser._id, {});
const sessionCookie = await lucia.createSessionCookie(session.id);
event.cookies.set(sessionCookie.name, sessionCookie.value, {
	path: '.',
	...sessionCookie.attributes
});

const { session, user } = await lucia.validateSession(sessionId);

I'm still learning this whole user auth thing so I could be doing something fundamentally wrong, but I've been banging my head against a wall for hours now so some delirium is expected

@Kingnoba
Copy link

Kingnoba commented Aug 24, 2024

declare module "lucia" {
    interface Register {
        Lucia: typeof lucia;
        DatabaseUserAttributes: User;
        UserId: ObjectId
    }
}

I mean that's in the docs, but I'm one of those crazy untalented devs who don't like killing themselves with TypeScript, so instead made a custom adapter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something ain't right...
Projects
None yet
Development

No branches or pull requests

7 participants