如何为特定路由使用中间件?
How to use a middleware for a specific route, among other ones?
我的简化路由类似于
r.Route("/api/v1", func(r chi.Router) {
r.Route("/case", func(r chi.Router) {
// generic case - for everyone
r.Get("/{uuid}", caseGetByUuid)
r.Put("/", casePut)
// all cases only available to admins
// r.Use(ensureAdminUser) // ← this is the place I have an error
r.Get("/", caseGetAll)
}
// admin endpoint
r.Route("/admin", func(r chi.Router) {
// ensure that the user is an admin
r.Use(ensureAdminUser)
r.Route("/user", func(r chi.Router) {
r.Route("/token", func(r chi.Router) { // /admin/user/token
r.Get("/", userTokenGetAll)
r.Put("/", userTokenCreate)
r.Delete("/", userTokenDelete)
})
})
})
})
second 路由 (/admin
) 受中间件限制,如果不满足特定约束,该中间件将断开链。中间件放在所有路由之前。
我想在 第一个 路由 (/case
) 中进行类似的过滤,但只针对一个路由(三个中的一个)。取消注释 r.Use(ensureAdminUser)
会导致
panic: chi: all middlewares must be defined before routes on a mux
我也不能为 /case
设置两条路线。
有没有办法保留路由/case
并限制root调用的一种方法?
如果不是,我将为受限情况创建替代路线。
您可以将中间件和后续路由包装在它们自己的 group(强调我的)中:
// Group adds a new inline-Router along the current routing
// path, with a fresh middleware stack for the inline-Route.
Group(fn func(r Router)) Router
r.Route("/api/v1", func(r chi.Router) {
r.Route("/case", func(r chi.Router) {
// generic case - for everyone
r.Get("/{uuid}", caseGetByUuid)
r.Put("/", casePut)
// all cases only available to admins
r.Group(func(r chi.Router) {
r.Use(ensureAdminUser)
r.Get("/", caseGetAll)
})
}
})
它也适用于 sub-router 和 r.Route
。
当中间件仅应用于一个路由时,另一种选择是 r.With
,它允许您“内联”中间件:
r.Route("/api/v1", func(r chi.Router) {
r.Route("/case", func(r chi.Router) {
// generic case - for everyone
r.Get("/{uuid}", caseGetByUuid)
r.Put("/", casePut)
// all cases only available to admins
r.With(ensureAdminUser).Get("/", caseGetAll)
}
})
我的简化路由类似于
r.Route("/api/v1", func(r chi.Router) {
r.Route("/case", func(r chi.Router) {
// generic case - for everyone
r.Get("/{uuid}", caseGetByUuid)
r.Put("/", casePut)
// all cases only available to admins
// r.Use(ensureAdminUser) // ← this is the place I have an error
r.Get("/", caseGetAll)
}
// admin endpoint
r.Route("/admin", func(r chi.Router) {
// ensure that the user is an admin
r.Use(ensureAdminUser)
r.Route("/user", func(r chi.Router) {
r.Route("/token", func(r chi.Router) { // /admin/user/token
r.Get("/", userTokenGetAll)
r.Put("/", userTokenCreate)
r.Delete("/", userTokenDelete)
})
})
})
})
second 路由 (/admin
) 受中间件限制,如果不满足特定约束,该中间件将断开链。中间件放在所有路由之前。
我想在 第一个 路由 (/case
) 中进行类似的过滤,但只针对一个路由(三个中的一个)。取消注释 r.Use(ensureAdminUser)
会导致
panic: chi: all middlewares must be defined before routes on a mux
我也不能为 /case
设置两条路线。
有没有办法保留路由/case
并限制root调用的一种方法?
如果不是,我将为受限情况创建替代路线。
您可以将中间件和后续路由包装在它们自己的 group(强调我的)中:
// Group adds a new inline-Router along the current routing
// path, with a fresh middleware stack for the inline-Route.
Group(fn func(r Router)) Router
r.Route("/api/v1", func(r chi.Router) {
r.Route("/case", func(r chi.Router) {
// generic case - for everyone
r.Get("/{uuid}", caseGetByUuid)
r.Put("/", casePut)
// all cases only available to admins
r.Group(func(r chi.Router) {
r.Use(ensureAdminUser)
r.Get("/", caseGetAll)
})
}
})
它也适用于 sub-router 和 r.Route
。
当中间件仅应用于一个路由时,另一种选择是 r.With
,它允许您“内联”中间件:
r.Route("/api/v1", func(r chi.Router) {
r.Route("/case", func(r chi.Router) {
// generic case - for everyone
r.Get("/{uuid}", caseGetByUuid)
r.Put("/", casePut)
// all cases only available to admins
r.With(ensureAdminUser).Get("/", caseGetAll)
}
})