代码之家  ›  专栏  ›  技术社区  ›  Mlouden

NESTJS EXPRESS-SSION REDIS:每个用户的cookie

  •  0
  • Mlouden  · 技术社区  · 3 年前

    我有一个NestJs应用程序,其中包括PassportJs、Express Session和Redis作为会话存储。事实上,我正在尝试实现一个记住我的功能,但我遇到了一个问题,不明白为什么它不起作用。在数据库中成功创建的会话没有任何错误,除了存储在数据库中的cookie具有cookie.maxAge=null和cookie.expires=null。知道吗?

    app.module.ts

    export class AppModule implements NestModule{
        
    constructor(@InjectConnection(ConnectionName.DB_ALPHA_REDIS_CONNECTION_NAME) private readonly connection: Redis) {}
          configure(consumer: MiddlewareConsumer) {
            consumer
              .apply(
                session({
                  name: process.env.ALPHA_AUTH_SESSION,
                  store: new RedisStore({ client: this.connection }),
                  saveUninitialized: false,
                  secret: process.env.SESSION_SECRET,
                  rolling: false,
                  resave: false,
                  cookie:{ httpOnly: true, secure: false, sameSite: true }
                }),
                passport.initialize(),
                passport.session(),
              )
              .forRoutes('*');
          }  
        }
    

    local-auth.guard.ts

    @Injectable()
    export class LocalAuthGuard extends AuthGuard('local'){
    
        async canActivate(context: ExecutionContext){
           
            const REQUEST = context.switchToHttp().getRequest()
            const RESPONSE = context.switchToHttp().getResponse()
    
            const BODY = plainToClass(LoginBody, REQUEST.body)
    
            const ERRORS = await validate(BODY)
    
            const ERR_MESSAGES = ERRORS.flatMap(({ constraints }) =>
                Object.values(constraints),
            );
    
            if(ERR_MESSAGES.length > 0)
                RESPONSE.status(404).send(buildResponse(404, 'There is some errors', ERR_MESSAGES))
    
            REQUEST.sessionStore.ttl = BODY.rememberMe ? 60 * 60 : 60
            REQUEST.session.cookie.maxAge = BODY.rememberMe ? 60 * 60 * 1000 : 60 * 1000
    
            // return 3600 as expected
            console.log( REQUEST.sessionStore.ttl) 
    
            /**
            return as expected
            cookie: {
              path: '/',
              _expires: 2023-06-20T00:24:26.712Z,
              originalMaxAge: 3600000,
              httpOnly: true,
              secure: false,
              sameSite: true
            }
            Inside redis cookie.originalMaxAge = null
            cookie.expires = null 
            */
            console.log( REQUEST.session.cookie)
    
            const RESULT = (await super.canActivate(context)) as boolean
            
            await super.logIn(REQUEST)
            return RESULT
        }
    
    }
    
    

    redis数据库内部:

    {"cookie":{"originalMaxAge":null,"expires":null,"secure":false,"httpOnly":true,"path":"/","sameSite":true},"passport":{"user":{"id":"648a59999f34ed94915ed3ba"}}}
    
    1 回复  |  直到 3 年前
        1
  •  1
  •   MWY    3 年前

    我认为一个可能的解决方案是在LocalAuthGuard的canActivate方法中使用REQUEST.session.save(),以确保在更改maxAge和ttl后正确保存会话。您可以尝试以下更改:

    @Injectable()
    export class LocalAuthGuard extends AuthGuard('local'){
    
        async canActivate(context: ExecutionContext){
           
            const REQUEST = context.switchToHttp().getRequest()
            const RESPONSE = context.switchToHttp().getResponse()
    
            const BODY = plainToClass(LoginBody, REQUEST.body)
    
            const ERRORS = await validate(BODY)
    
            const ERR_MESSAGES = ERRORS.flatMap(({ constraints }) =>
                Object.values(constraints),
            );
    
            if(ERR_MESSAGES.length > 0)
                RESPONSE.status(404).send(buildResponse(404, 'There are some errors', ERR_MESSAGES))
    
            REQUEST.sessionStore.ttl = BODY.rememberMe ? 60 * 60 : 60
            REQUEST.session.cookie.maxAge = BODY.rememberMe ? 60 * 60 * 1000 : 60 * 1000
    
            // Save the session after modifying ttl and maxAge
            REQUEST.session.save(err => {
              if (err) {
                console.error(err);
              }
            });
    
            // return 3600 as expected
            console.log( REQUEST.sessionStore.ttl) 
    
            /**
            return as expected
            cookie: {
              path: '/',
    ',
              _expires: 2023-06-20T00:24:26.712Z,
              originalMaxAge: 3600000,
              httpOnly: true,
              secure: false,
              sameSite: true
            }
            */
            console.log( REQUEST.session.cookie)
    
            const RESULT = (await super.canActivate(context)) as boolean
            
            await super.logIn(REQUEST)
            return RESULT
        }
    
    }
    
    

    另一种解决方案是,在调用super.logIn(REQUEST)后尝试设置maxAge和ttl。:

    @Injectable()
    export class LocalAuthGuard extends AuthGuard('local'){
    
        async canActivate(context: ExecutionContext){
           
            const REQUEST = context.switchToHttp().getRequest()
            const RESPONSE = context.switchToHttp().getResponse()
    
            const BODY = plainToClass(LoginBody, REQUEST.body)
    
            const ERRORS = await validate(BODY)
    
            const ERR_MESSAGES = ERRORS.flatMap(({ constraints }) =>
                Object.values(constraints),
            );
    
            if(ERR_MESSAGES.length > 0)
                RESPONSE.status(404).send(buildResponse(404, 'There is some errors', ERR_MESSAGES))
    
            const RESULT = (await super.canActivate(context)) as boolean
            
            await super.logIn(REQUEST)
    
            REQUEST.sessionStore.ttl = BODY.rememberMe ? 60 * 60 : 60
            REQUEST.session.cookie.maxAge = BODY.rememberMe ? 60 * 60 * 1000 : 60 * 1000
    
            // Save the session after modifying ttl and maxAge
            REQUEST.session.save(err => {
              if (err) {
                console.error(err);
              }
            });
    
            // return 3600 as expected
            console.log( REQUEST.sessionStore.ttl) 
    
            /**
            return as expected
            cookie: {
              path: '/',
              _expires: 2023-06-20T00:24:26.712Z,
              originalMaxAge: 3600000,
              httpOnly: true,
              secure: false,
              sameSite: true
            }
            */
            console.log( REQUEST.session.cookie)
    
            return RESULT
        }
    
    }