You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express/GraphQL中连续登录后Passport的context.req.user为undefined

Passport.js + GraphQL: context.req.user Returns undefined on Second Login Attempt

Hey there, let's work through this issue you're hitting with Passport.js and your GraphQL setup. You mentioned the loginUser mutation works perfectly on the first try, but when you attempt to login a second time, context.req.user comes back as undefined instead of the Passport user data you expect.

First, here's the key snippet from your Passport config (around line 28) for reference:

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser(async (id: string, done) => {
  try {
    const user = await User.findById(id);
    done(null, user);
  } catch (err) {
    done(err);
  }
});

Let's go through common fixes and checks to resolve this:

  • Confirm Middleware Order & Session Configuration
    Passport depends on Express's session middleware to persist user data across requests. Make sure your middleware loads in this exact order: session first, then Passport init/session, then your GraphQL middleware. For example:

    // Session setup (must run first!)
    app.use(session({
      secret: process.env.SESSION_SECRET || 'dev-only-secret',
      resave: false,
      saveUninitialized: true, // Try setting this to true if sessions drop unexpectedly
      cookie: {
        secure: process.env.NODE_ENV === 'production',
        httpOnly: true,
        sameSite: 'lax'
      }
    }));
    
    // Passport initialization
    app.use(passport.initialize());
    app.use(passport.session());
    
    // GraphQL middleware (last in the chain)
    app.use('/graphql', graphqlHTTP({
      schema,
      context: ({ req }) => ({ req }) // Critical: pass the request object to context!
    }));
    

    The saveUninitialized flag is a frequent culprit here—if it's set to false, the session won't save to storage unless you explicitly modify it, which might not happen properly after your first login.

  • Double-Check GraphQL Context Setup
    Ensure your GraphQL server is actually passing the incoming request object (req) to the resolver context. If you're using Apollo Server, it should look like this:

    const server = new ApolloServer({
      schema,
      context: ({ req }) => ({ req }) // Makes req available in all resolvers
    });
    

    Without this, your resolvers can't access the session data Passport uses to populate req.user.

  • Validate Your Passport Strategy
    In your authentication strategy (like LocalStrategy), confirm you're correctly calling done(null, user) when authentication succeeds. If you skip this or pass false instead, Passport won't serialize the user to the session:

    passport.use(new LocalStrategy(
      async (username, password, done) => {
        try {
          const user = await User.findOne({ username });
          if (!user) return done(null, false, { message: 'User not found' });
          
          const isPasswordValid = await user.comparePassword(password);
          if (!isPasswordValid) return done(null, false, { message: 'Invalid password' });
    
          // This line is essential—pass the user to done() to serialize it
          return done(null, user);
        } catch (err) {
          return done(err);
        }
      }
    ));
    
  • Check Session Storage
    If you're using the default in-memory session store (only for development!), it might be clearing sessions unexpectedly. For production, use a persistent store like Redis or MongoDB, but even in dev, make sure your server isn't restarting between requests. If you're using a persistent store, verify its connection details are correct.

  • Inspect Session Cookies
    Use your browser's dev tools to check if the session cookie is being sent with the second login request. If it's missing:

    • In development, set secure: false (since you're using HTTP, not HTTPS)
    • Ensure httpOnly: true isn't blocking the cookie from being sent
    • Adjust sameSite to lax or none (if cross-origin) based on your setup

If none of these steps fix the issue, sharing your full server/server.ts config or a minimal reproducible repository would help dig deeper.

内容的提问来源于stack exchange,提问作者Falieson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:17:11