如何在 Express 和 GraphQL/Apollo 服务器之间共享和修改变量?

问题描述 投票:0回答:1

我的申请背景

我有一个安装了

apollo-server-express
包的 Express 应用程序,它允许我将 GraphQL 服务器附加到正在运行的 Express 服务器。

Express 服务器用于身份验证/授权(使用 Keycloak 和 Passport),GraphQL 服务器作为 API 层用于查询数据。

我想要完成什么

实现一种在用户处于非活动状态 10 分钟后自动注销的方法。 “非活动”定义为用户无法向 GraphQL 服务器进行查询。

我目前的策略

在初始化 Express 应用程序时创建一个全局变量,用于跟踪每个登录用户以及他们上次发出请求的时间。示例:

const userSessionTracker = {
    userId1: 300000, // a user's timer: last time they logged in/made a request (in ms)
    userId2: 5000,
    ...
}

每次用户登录/发出请求时,应用程序都会将计时器重置回 0。下次发出请求时,如果计时器超过 10 分钟,应用程序会将用户注销。

问题

当用户调用 GraphQL 查询时,我想检查/重置 GraphQL 查询解析器内的计时器。我怎样才能做到这一点?

我尝试过的

  • userSessionTracker
    传递到 Apollo 服务器的
    context
    ,使得可以从解析器的
    contextValue
  • 访问该变量
  • 尝试从解析器内部编辑
    userSessionTracker
  • console.log(userSessionTracker)
    来自 Express 服务器
  • 预计
    userSessionTracker
    显示 GraphQL 解析器所做的编辑,但发现它仍保持编辑前的状态

总之,我可以从 GraphQL 解析器内部访问

userSessionTracker
变量,但我无法编辑它,也无法从 Express 应用程序访问编辑后的版本。

这似乎是设计使然,正如 Apollo 文档指出的那样“解析器永远不应该破坏性地修改 contextValue 参数”。我怎样才能绕过这个限制?

express graphql keycloak apollo apollo-server
1个回答
0
投票

解析器是实现此逻辑的错误位置 - 您需要在

context
函数中完成所有操作。在任何查询和解析器触发之前,来自用户的每个 GraphQL 请求都必须首先经过
context
函数,因此它是放置身份验证和超时逻辑的中心位置。解析器只能读取上下文,而不能更改它。

您甚至不需要查看解析器内的

userSessionTracker
,您只需要知道请求背后是否有经过身份验证的用户。

如果您使用 JWT,那么您可以简单地让 JWT 在 10 分钟后过期,但在过期之前随时收到请求时刷新它 - 这样每个经过身份验证的查询都会重新启动时钟。

存储会话过期服务器端意味着数据库或共享缓存,如果您想要扩展到多个服务器,您可以在其中管理过期时间。

© www.soinside.com 2019 - 2024. All rights reserved.