【问题标题】:How to restrict route access in ktor framework?如何在 ktor 框架中限制路由访问?
【发布时间】:2022-01-10 06:10:17
【问题描述】:

ktor框架如何限制route访问?

//only admin           
post("/add") {
   call.respondText { "add" }
}

post("/delete") {
   call.respondText { "delete" }
}
        

【问题讨论】:

  • 能否更详细地描述您的问题?你想实现什么类型的中间件?另外,你提到的 API 还没有发布。
  • @AlekseiTirman laravel.com/docs/8.x/middleware 我想通过插件限制路由访问。
  • 在Ktor中你可以拦截管道来达到类似的效果。有关路由拦截的信息,请阅读文档ktor.io/docs/…
  • @AlekseiTirman 请给我一个例子。例如,我们有三个 post 方法,我们想限制它们。 //仅管理员 post("add") {} post("delete") {} //仅客户 post("show") {}

标签: kotlin ktor


【解决方案1】:

您可以编写一个方法来创建仅限制管理员访问的路由。在该方法内部,新创建的路由被拦截以注入代码进行验证。在以下示例中,如果标头 admin 具有值 1,则从管理员发出请求,否则 /add/delete 路由将返回具有 401 Unauthorized 状态的响应。

import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.util.pipeline.*

fun main() {
    embeddedServer(Netty, port = 5555, host = "0.0.0.0") {
        routing {
            admin {
                post("/add") {
                    call.respondText { "add" }
                }

                post("/delete") {
                    call.respondText { "delete" }
                }
            }

            post("/show") {
                call.respondText { "show" }
            }
        }
    }.start(wait = false)
}

private val validationPhase = PipelinePhase("Validate")

fun Route.admin(build: Route.() -> Unit): Route {
    val route = createChild(AdminSelector())

    route.insertPhaseAfter(ApplicationCallPipeline.Features, Authentication.ChallengePhase)
    route.insertPhaseAfter(Authentication.ChallengePhase, validationPhase)
    route.intercept(validationPhase) {
        if (!isAdmin(call.request)) {
            call.respond(HttpStatusCode.Forbidden)
            finish()
        }
    }
    route.build()
    return route
}

class AdminSelector: RouteSelector() {
    override fun evaluate(context: RoutingResolveContext, segmentIndex: Int) = RouteSelectorEvaluation.Transparent
}

fun isAdmin(request: ApplicationRequest): Boolean {
    return request.headers["admin"] == "1"
}

【讨论】:

  • 非常感谢。您是否查看过 Ktor 的第 2 版?创建自定义插件变得更加容易。是否可以使用插件实现此代码? ktor.io/docs/eap/custom-plugins.html
  • 是的,但需要编写一个钩子。此外,您的问题可以通过身份验证插件ktor.io/docs/auth.html 解决。
  • 在使用自定义插件 2.0.0-beta-1 时无法正常工作。甚至非管理员仍然被检查
  • @ronscript 此示例适用于 Ktor 1.6.7。
猜你喜欢
  • 2018-12-26
  • 2020-01-15
  • 2021-11-04
  • 2020-09-28
  • 2015-09-14
  • 2011-12-16
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
相关资源
最近更新 更多