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

Strapi中GraphQL端点添加策略时ctx.session为空的问题咨询

解决GraphQL Bearer Token请求下ctx.session为空的问题

Hey there! 很高兴看到你把GraphQL和MongoDB对接得这么顺利,咱们来聊聊你遇到的session问题~

为什么ctx.session是空的?

核心原因是Bearer Token认证和传统的Session认证是两套完全不同的机制:

  • 传统Session依赖浏览器自动携带的Cookie,服务器通过Cookie里的Session ID找到对应的会话数据,填充ctx.session。
  • 而你用的Bearer Token是放在Authorization请求头里的,默认的Session中间件根本不会识别这个Token,自然也就没法生成或找到对应的Session,所以ctx.session一直是空的。

这个场景下的Session工作机制

如果你的服务选择用Bearer Token(比如JWT)做认证,那其实可以不用依赖Session:

  1. 客户端每次请求都在Header里带上Bearer <token>;
  2. 服务器端通过中间件解析这个Token,验证签名的合法性;
  3. 解析后可以直接从Token的Payload里拿到用户的基础信息(比如ID、权限),或者根据Token里的用户ID去数据库查询最新的用户数据;
  4. 把解析/查询到的用户信息挂载到GraphQL的Context上(比如ctx.user),供后续的权限策略使用。

是否每次请求都需要查询用户?

这取决于你的业务需求:

  • 不需要每次查:如果你的Token是JWT,且Payload里已经包含了权限、用户名等常用信息,只要Token没过期,直接解析Payload就能拿到用户信息,不用查数据库,性能更好。但要注意,如果用户的权限等信息在Token有效期内发生了变更,这种方式没法实时获取最新状态。
  • 需要每次查:如果你的业务要求实时获取用户的最新数据(比如权限变更、账号状态),那每次请求都去MongoDB查询一次用户是更稳妥的选择。可以搭配Redis之类的缓存来优化查询性能,避免频繁操作数据库。

具体的解决步骤

  1. 添加Token解析中间件:在GraphQL的Context生成逻辑里,专门处理Authorization头里的Bearer Token:
// 示例:Node.js + Express + GraphQL的Context配置
const jwt = require('jsonwebtoken');
const User = require('./models/User');

const createContext = async ({ req }) => {
  const authHeader = req.headers.authorization;
  let user = null;

  if (authHeader && authHeader.startsWith('Bearer ')) {
    try {
      // 提取Token
      const token = authHeader.split(' ')[1];
      // 验证并解析Token
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      // 可选:根据用户ID查询数据库获取最新信息
      user = await User.findById(decoded.userId).select('-password');
    } catch (err) {
      // Token无效或过期,这里可以根据业务逻辑处理(比如抛出错误、返回空)
      console.error('Token验证失败:', err);
    }
  }

  // 将用户信息挂载到Context上
  return { user };
};
  1. 调整权限策略逻辑:在你的GraphQL端点策略里,不再依赖ctx.session,而是使用ctx.user来做权限校验:
// 示例:检查用户是否已登录的策略
const isAuthenticated = (ctx) => {
  if (!ctx.user) {
    throw new Error('请先登录');
  }
  return true;
};
  1. (可选)如果一定要用Session:如果你有特殊场景需要结合Token和Session,可以在解析Token成功后,手动创建或更新Session:
// 在createContext函数里,解析Token成功后:
req.session.user = user;
await req.session.save();

不过这种方式其实有点冗余,除非你有必须同时依赖Session的业务场景,否则不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:44:09