Caliban 将 Cookie 冒泡到 Http4s 中间件的正确方法

问题描述

tl;dr 如何从 caliban GraphQLApi 中提取一些信息并将其作为 cookie(即在中间件中)附加到 http4s.Request

我正在使用 Caliban 设置一个 GraphQL 服务器,并且接口是通过 Http4s 提供的。以下是部分服务器定义

 ZIO
    .runtime[MEnv]
    .flatMap(k = implicit runtime => 
       for{
          interpreter <- BaseGraphQLApi.api.interpreter
          publicInterpreter <- MinervaPublicGraphQLApi.api.interpreter
          secureRoutes : HttpRoutes[MinervaTask] = AuthMiddleware(authModule,Http4sAdapter.makeHttpService(interpreter))
           _ <- BlazeServerBuilder[MinervaTask](ExecutionContext.global)
                  .withServiceErrorHandler(errorHandler)
                  .bindHttp(8088,"localhost")
                  .withHttpApp(
                     Router[MinervaTask](
                         "/api/graphql/user" -> secureRoutes,"/api/graphql" -> CORS(Http4sAdapter.makeHttpService(publicInterpreter))
                     ).orNotFound
                   )
                   .resource
                   .toManaged
                   .useForever
   } yield zio.ExitCode.success

现在假设我有一个登录服务,我想将查询返回的一些信息存储为 cookie。问题我似乎找不到从 GraphQL 端提取此信息并将其传递到 middleware 中的方法,然后可以将其作为 cookie 附加到 response

这是我的 caliban api 的一部分

case class Queries(
   someAuthReq: SomeRequest => RIO[AuthService,JwtToken],)

implicit val userArgsSchema  = gen[SomeRequest]

val api: GraphQL[Console with Clock with AuthService] =
  graphQL(
    RootResolver(
      Queries(
        args => AuthService.doStuff(args.username),//this returns some data that belongs in a cookie
      )
    )
) 

在 GraphQL 中处理 cookie 似乎是一个普遍存在的问题。我发现了来自各种语言/框架的讨论,普遍的共识是在 GraphQL 之外更好地处理身份验证。虽然我很欣赏这些建议,并且可能最终会沿着这条路走下去,但我仍然认为这是一个有趣的问题,因为它突破了引用透明度的界限,而且很难正确地确定类型。

我尝试过类似以下的操作,但类型不一致,还有一个单独的问题 FiberRef 所在的位置...

def cookieMiddle(service: HttpRoutes[MinervaTask],jwtF : FiberRef[JwtToken])
  : HttpRoutes[MinervaTask] = 
 Http4sAdapter.provideSomeLayerFromRequest(
  service,r => jwtF.get.flatMap(jwt => 
     service(r).flatMap{
       case Status.Successful(resp) =>
          ZLayer.succeed(resp.addCookie("X-Identification",jwt.value,Some(HttpDate.MaxValue)))
       case resp =>
          ZLayer.succeed(resp)
     }
  )
)

另一个想法是 ref 存在于环境中的 Zlayer 中,我可以在中间件中提取它,但我似乎也无法使其正常工作

如果有任何建议,我将不胜感激...

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...