{"id":13872276,"url":"https://github.com/ml-archive/gatekeeper","last_synced_at":"2025-07-16T02:30:29.505Z","repository":{"id":47315439,"uuid":"80074248","full_name":"ml-archive/gatekeeper","owner":"ml-archive","description":"Rate limiting middleware for Vapor 👮","archived":true,"fork":false,"pushed_at":"2021-09-03T08:35:36.000Z","size":75,"stargazers_count":74,"open_issues_count":1,"forks_count":14,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-10-26T22:16:22.938Z","etag":null,"topics":["rate-limiting","rate-limits","server-side-swift","swift","tose","vapor","vapor-3"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ml-archive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-26T01:01:26.000Z","updated_at":"2024-05-24T14:27:59.000Z","dependencies_parsed_at":"2022-09-13T22:12:02.837Z","dependency_job_id":null,"html_url":"https://github.com/ml-archive/gatekeeper","commit_stats":null,"previous_names":["nodes-vapor/gatekeeper"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ml-archive%2Fgatekeeper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ml-archive%2Fgatekeeper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ml-archive%2Fgatekeeper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ml-archive%2Fgatekeeper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ml-archive","download_url":"https://codeload.github.com/ml-archive/gatekeeper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226095621,"owners_count":17572963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rate-limiting","rate-limits","server-side-swift","swift","tose","vapor","vapor-3"],"created_at":"2024-08-05T23:00:38.458Z","updated_at":"2024-11-23T20:30:48.385Z","avatar_url":"https://github.com/ml-archive.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# Gatekeeper 👮\n[![Swift Version](https://img.shields.io/badge/Swift-5.3-brightgreen.svg)](http://swift.org)\n[![Vapor Version](https://img.shields.io/badge/Vapor-4-30B6FC.svg)](http://vapor.codes)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nodes-vapor/gatekeeper/master/LICENSE)\n\nGatekeeper is a middleware that restricts the number of requests from clients, based on their IP address **(can be customized)**.\nIt works by adding the clients identifier to the cache and count how many requests the clients can make during the Gatekeeper's defined lifespan and give back an HTTP 429(Too Many Requests) if the limit has been reached. The number of requests left will be reset when the defined timespan has been reached.\n\n**Please take into consideration that multiple clients can be using the same IP address. eg. public wifi**\n\n\n## 📦 Installation\n\nUpdate your `Package.swift` dependencies:\n\n```swift\n.package(url: \"https://github.com/nodes-vapor/gatekeeper.git\", from: \"4.0.0\"),\n```\n\nas well as to your target (e.g. \"App\"):\n\n```swift\ntargets: [\n    .target(name: \"App\", dependencies: [..., \"Gatekeeper\", ...]),\n    // ...\n]\n```\n\n## Getting started 🚀\n\n### Configuration\n\nin configure.swift:\n```swift\nimport Gatekeeper\n\n// [...]\n\napp.caches.use(.memory)\napp.gatekeeper.config = .init(maxRequests: 10, per: .second)\n```\n\n### Add to routes\n\nYou can add the `GatekeeperMiddleware` to specific routes or to all.\n\n**Specific routes**\nin routes.swift:\n```swift\nlet protectedRoutes = router.grouped(GatekeeperMiddleware())\nprotectedRoutes.get(\"protected/hello\") { req in\n    return \"Protected Hello, World!\"\n}\n```\n\n**For all requests**\nin configure.swift:\n```swift\n// Register middleware\napp.middlewares.use(GatekeeperMiddleware())\n```\n\n#### Customizing config\nBy default `GatekeeperMiddleware` uses `app.gatekeeper.config` as its configuration.\nHowever, you can pass a custom configuration to each `GatekeeperMiddleware` type via the initializer\n`GatekeeperMiddleware(config:)`. This allows you to set configuration on a per-route basis.\n\n## Key Makers 🔑\nBy default Gatekeeper uses the client's hostname (IP address) to identify them. This can cause issues where multiple clients are connected from the same network. Therefore, you can customize how Gatekeeper should identify the client by using the `GatekeeperKeyMaker` protocol.\n\n`GatekeeperHostnameKeyMaker` is used by default.\n\nYou can configure which key maker Gatekeeper should use in `configure.swift`:\n```swift\napp.gatekeeper.keyMakers.use(.hostname) // default\n```\n\n### Custom key maker\nThis is an example of a key maker that uses the user's ID to identify them.\n```swift\nstruct UserIDKeyMaker: GatekeeperKeyMaker {\n    public func make(for req: Request) -\u003e EventLoopFuture\u003cString\u003e {\n        let userID = try req.auth.require(User.self).requireID()        \n        return req.eventLoop.future(\"gatekeeper_\" + userID.uuidString)\n    }\n}\n```\n\n```swift\nextension Application.Gatekeeper.KeyMakers.Provider {\n    public static var userID: Self {\n        .init { app in\n            app.gatekeeper.keyMakers.use { _ in UserIDKeyMaker() }\n        }\n    }\n}\n```\n**configure.swift:**\n```swift\napp.gatekeeper.keyMakers.use(.userID)\n```\n\n## Cache 🗄\nGatekeeper uses the same cache as configured by `app.caches.use()` from Vapor, by default.\nTherefore it is **important** to set up Vapor's cache if you're using this default behaviour. You can use an in-memory cache for Vapor like so:\n\n**configure.swift**:\n```swift\napp.cache.use(.memory)\n```\n\n### Custom cache\nYou can override which cache to use by creating your own type that conforms to the `Cache` protocol from Vapor. Use `app.gatekeeper.caches.use()` to configure which cache to use.\n\n\n## Credits 🏆\n\nThis package is developed and maintained by the Vapor team at [Nodes](https://www.nodesagency.com).\nThe package owner for this project is [Christian](https://github.com/cweinberger).\nSpecial thanks goes to [madsodgaard](https://github.com/madsodgaard) for his work on the Vapor 4 version!\n\n## License 📄\n\nThis package is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fml-archive%2Fgatekeeper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fml-archive%2Fgatekeeper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fml-archive%2Fgatekeeper/lists"}