问题描述
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 (将#修改为@)