[英]How to combine AuthedRoutes and HttpRoutes in http4s?
当它们都与<+>
结合时,是否有任何规则如何将AuthedRoutes
优先于HttpRoutes
因为我收到 401 这样的组合authRoute <+> route
,调用时:
GET /non-authed-route
当我重新排序路由route <+> authRoute
时,行为发生了变化,并且我收到了 200 个相同的请求。
当您需要使用 5 个以上需要组合的路由并且其中一些可能同时包含常规和安全端点时,它可能会更加混乱。
因此,尽管该问题缺少一些上下文信息或代码,但我将假设您的问题与常见问题足够相似:
首先,我假设您的代码具有这种近似形式,并且使用AuthedRoutes.of
( 在此处定义)和AuthMiddleware
:
val moonAuthedRoutes: AuthedRoutes[F, Int] = AuthedRoutes.of {
case GET -> / sky / moon as T(42)
}
val marsRoutes: HttpRoutes[F] = HttpRoutes.of {
case GET -> / sky / mars
}
// assuming you have your authedMiddleware
val moonRoutes = authedMiddleware(moonAuthedRoutes)
val composedRoutes = moonRoutes <+> marsRoutes
现在,如果您了解所涉及的别名的类型,以及打开Kleisli
和OptionT
后它们归结为什么,它会有所帮助:
type HttpRoutes[F, T]
= Kleisli[OptionT[F, ?], Request[F, T], Response[F]]
~~ Request[F] => F[Option[Response[F]]
type AuthedRoutes[F, T]
= Kleisli[OptionT[F, ?], AuthedRequest[F, T], Response[F]]
~~ (T, Request[F]) => F[Option[Response[F]]
本质上,一个 function 接受 HTTP 请求和一些身份验证上下文,并且可能给出计算一些响应或没有响应(在F
中的计算内)。 要将此AuthedRoutes
转换为HttpRoutes
,请使用身份验证中间件: AuthedRoutes
上的包装器接受请求,尝试从中提取T
,如果成功,则使用该T
包装请求并将其传递给AuthedRoutes
,如在这行代码中完成。 如果中间件无法验证请求(即提取T
),则从这一行开始,它会短路并返回401 Unauthenticated响应。
现在, <+>
组合首先应用于moonRoutes
上的请求。 如果结果是一些响应,那就是组合路由返回的结果。 只有当moonRoutes
路由(在<+>
的左侧)返回F(None)
时,组合才会将请求传递给marsRoutes
。 特别是,当您给它一个未经身份验证的请求时, moonRoutes
返回一些401 composedRoutes
响应,这就是composerRoutes 返回的内容,而无需将请求传递给marsRoutes
。
但是,如果您交换顺序并编写composedRoutes = marsRoutes <+? moonRoutes
composedRoutes = marsRoutes <+? moonRoutes
,然后在marsRoutes
中回答对未认证端点的未认证请求; 而经过身份验证的请求首先在marsRoutes
中尝试,但失败(给出F(None)
),然后传递给moonRoutes
,成功。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.