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

React结合Express Session与Apollo后端,如何校验用户认证状态?

问题分析与解决方法

1. 修正后端认证判断逻辑

你的isAuthenticated函数错误地从req.userId取值,但实际上登录后你是把userId存在req.session.userId里的,必须修改这个函数:

function isAuthenticated(req: any) {
  // 从session中获取userId,而非req本身
  const userId: string = req?.session?.userId;
  return !!userId;
}

2. 前端Apollo Client必须携带会话凭证

前端请求后端时需要自动带上session cookie,必须在Apollo Client的配置中开启withCredentials: true:

// 示例Apollo Client配置
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';

const httpLink = createHttpLink({
  uri: 'http://localhost:4000/graphql',
  // 开启携带凭证,让浏览器自动传递session cookie
  withCredentials: true,
});

const client = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache(),
});

3. 修正CORS配置允许凭证传递

如果前端和后端跨域,CORS必须明确设置credentials: true,同时origin不能用通配符*,要指定具体的前端域名:

app.use(
  cors<cors.CorsRequest>({
    origin: 'http://localhost:3000', // 替换为你的前端实际域名
    credentials: true, // 允许跨域携带凭证
  }),
  // ...其他中间件
);

4. (可选)登录后手动保存session

在登录resolver中,设置userId后手动调用req.session.save(),确保会话及时持久化到Redis,避免异步操作导致的session未保存问题:

signInUser: async (_, { user }, context) => {
  const { username, password } = user;
  const foundUser = await UserModel.findOne({ username });
  if (foundUser) {
    const match = await bcrypt.compare(password, foundUser.password);
    if (match && context.req.session) {
      context.req.session.userId = foundUser.id;
      // 手动保存session到Redis
      await new Promise((resolve, reject) => {
        context.req.session.save((err: any) => {
          if (err) reject(err);
          else resolve(null);
        });
      });
      return { message: 'Signed in successfully!', status: 'success' };
    }
  }
  // 补充登录失败的返回逻辑
  return { message: 'Invalid username or password', status: 'error' };
},

验证流程

  1. 登录接口调用成功后,检查Redis中是否存在对应的session数据,确认userId已存入
  2. 调用isAuthenticated查询时,后端能从req.session.userId获取到值,返回true
  3. 前端通过useAuth hook能正确拿到认证状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:50:20