Papooch / nestjs-cls

A continuation-local storage (async context) module compatible with NestJS's dependency injection.
https://papooch.github.io/nestjs-cls/
MIT License
434 stars 28 forks source link

adding session id #17

Closed deeeed closed 2 years ago

deeeed commented 2 years ago

Hi,

I am trying to setup the context to holds my sessionId as well but the ClsModule setup is always running before my SessionModule setup (hence session is not available in ClsModule context).

    SessionModule.forRoot({
      session: {
        secret: 'session secret...',
        resave: false,
        cookie: {
          maxAge: 60000,
        },
        genid: (req) => {
          console.log(`generate session id now`);
          return uuidv4();
        },
        saveUninitialized: true,
      },
    }),
    // Register the ClsModule and automatically mount the ClsMiddleware
    ClsModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        return {
          global: true,
          middleware: {
            mount: true,
            setup: (cls: ClsService, request: any) => {
              const userIp = getClientIp(request);
              const originalUrl = request['originalUrl'];
              const requestId = request['id'] + '';
              const user = request['user'] as User;
              let userId, email;
              if (user) {
                userId = user.id;
                email = user.email;
              }
              const trackingInfo = {
                requestId,
                originalUrl,
                userIp,
                userId,
                email,
              };
              console.log(`setting up context`, trackingInfo);
              cls.set(GLOBALS.CLS_TRACKING, trackingInfo);
            },
          },
        };
      },
    }),

If I look at the log I get:

setting up context...
generate session id now...

Any recommendation to fix this issue? Currently I create a separate interceptor that complements the setup and adds the session attribute to my context.

Papooch commented 2 years ago

Hi, I'm not familiar with SessionModule, but after a brief look at the code, I can see that they set up the middleware in a similar manner to ClsModule, so the middleware registration order probably follows the order in which Nest resolves the modules (they use topological sorting, but I don't really know how they treat global modules).

You might fix it by setting mount to false and mounting the ClsMiddleware in the root module (AppModule)

export class AppModule implements NestModule {
    configure(consumer: MiddlewareConsumer) {
        apply(ClsMiddleware).forRoutes('*');
    }
}

If that doesn't work, I was about to suggest the extra interceptor method, that you already use.

Another option would be to not use SessionModule and attach a plain old express-session middleware as outlined in the docs here https://docs.nestjs.com/techniques/session#session

Papooch commented 2 years ago

@deeeed Please tell me if your issue was resolved by one of the proposed solutions, so I can close it.