Gatekeeper 👮 (门卫)

Swift Version Vapor Version GitHub license

Gatekeeper 是一个中间件,它根据客户端的 IP 地址(可以自定义)限制来自客户端的请求数量。它的工作原理是将客户端的标识符添加到缓存中,并统计客户端在 Gatekeeper 定义的生命周期内可以发出的请求数量。如果达到限制,则返回 HTTP 429 (Too Many Requests) 错误。 剩余的请求数量将在定义的时限到达时重置。

请注意,多个客户端可能使用相同的 IP 地址。例如,公共 wifi。

📦 安装

更新你的 Package.swift 依赖

.package(url: "https://github.com/nodes-vapor/gatekeeper.git", from: "4.0.0"),

以及你的 target (例如 "App")

targets: [
    .target(name: "App", dependencies: [..., "Gatekeeper", ...]),
    // ...
]

开始使用 🚀

配置

在 configure.swift 中

import Gatekeeper

// [...]

app.caches.use(.memory)
app.gatekeeper.config = .init(maxRequests: 10, per: .second)

添加到路由

您可以将 GatekeeperMiddleware 添加到特定路由或所有路由。

特定路由 在 routes.swift 中

let protectedRoutes = router.grouped(GatekeeperMiddleware())
protectedRoutes.get("protected/hello") { req in
    return "Protected Hello, World!"
}

对于所有请求 在 configure.swift 中

// Register middleware
app.middlewares.use(GatekeeperMiddleware())

自定义配置

默认情况下,GatekeeperMiddleware 使用 app.gatekeeper.config 作为其配置。 但是,您可以通过初始化程序 GatekeeperMiddleware(config:) 将自定义配置传递给每个 GatekeeperMiddleware 类型。 这允许您按路由设置配置。

Key Makers 🔑 (密钥生成器)

默认情况下,Gatekeeper 使用客户端的主机名(IP 地址)来识别它们。 当多个客户端从同一网络连接时,这可能会导致问题。 因此,您可以使用 GatekeeperKeyMaker 协议自定义 Gatekeeper 应该如何识别客户端。

默认情况下使用 GatekeeperHostnameKeyMaker

您可以在 configure.swift 中配置 Gatekeeper 应使用的密钥生成器。

app.gatekeeper.keyMakers.use(.hostname) // default

自定义密钥生成器

这是一个使用用户 ID 来识别他们的密钥生成器的示例。

struct UserIDKeyMaker: GatekeeperKeyMaker {
    public func make(for req: Request) -> EventLoopFuture<String> {
        let userID = try req.auth.require(User.self).requireID()        
        return req.eventLoop.future("gatekeeper_" + userID.uuidString)
    }
}
extension Application.Gatekeeper.KeyMakers.Provider {
    public static var userID: Self {
        .init { app in
            app.gatekeeper.keyMakers.use { _ in UserIDKeyMaker() }
        }
    }
}

configure.swift

app.gatekeeper.keyMakers.use(.userID)

缓存 🗄

默认情况下,Gatekeeper 使用与 Vapor 的 app.caches.use() 配置相同的缓存。 因此,如果您使用此默认行为,重要的是设置 Vapor 的缓存。 您可以像这样为 Vapor 使用内存缓存

configure.swift:

app.cache.use(.memory)

自定义缓存

您可以通过创建自己的符合 Vapor 的 Cache 协议的类型来覆盖要使用的缓存。 使用 app.gatekeeper.caches.use() 配置要使用的缓存。

Credits 🏆 (贡献者)

此软件包由 Nodes 的 Vapor 团队开发和维护 ( https://www.nodesagency.com )。 该项目的软件包所有者是 Christian. 特别感谢 madsodgaard 为 Vapor 4 版本所做的工作!

License 📄 (许可证)

该软件包是根据 MIT license 获得许可的开源软件