一个简单的库,用于保护 POST 请求免受 CSRF(跨站请求伪造)攻击。
简单来说,就是诱骗用户发出 Web 应用程序可以接受的请求。 想象一个银行网站,它有一个 POST 请求可以将钱转入一个帐户。 如果恶意网站可以强制用户发送该 POST 请求(在他们登录时),那么攻击者可以诱骗用户转移资金。
CSRF 令牌通过确保 POST 请求的合法性来防止这种情况。 该网站向 GET 请求提供一个令牌,然后在处理 POST 请求时检查该令牌是否匹配。
诸如 SameSite cookies 等现代解决方案提供了类似的保护,但并非所有浏览器都支持。
在 Package.swift 的 dependencies 数组中添加 CSRF 库
dependencies: [
// ...,
.package(name: "VaporCSRF", url: "https://github.com/brokenhandsio/vapor-csrf.git", from: "1.0.0")
],
还要确保将其作为依赖项添加到您的 target 中
targets: [
.target(name: "App", dependencies: [
.product(name: "Vapor", package: "vapor"),
// ...,
"VaporCSRF"]),
// ...
]
您必须在使用 CSRF 的所有路由上使用 SessionsMiddleware
。 您可以在 configure.swift 中全局启用它,如下所示:
app.middleware.use(app.sessions.middleware)
有关会话的更多信息,请参阅文档。
在可能返回您想要保护的 POST 请求的 GET 路由中,将 CSRF 令牌存储在会话中
let csrfToken = req.csrf.storeToken()
此函数返回一个您可以传递到您的 HTML 页面的令牌。 例如,使用 Leaf 看起来像这样:
let csrfToken = req.csrf.storeToken()
let context = MyPageContext(csrfToken: csrfToken)
return req.view.render("myPage", context)
然后,您需要在提交表单时返回令牌。 使用 Leaf,这看起来像这样:
<form method="post">
<input type="hidden" name="csrfToken" value="#(csrfToken)">
<input type="submit" value="Submit">
</form>
您可以使用中间件或手动验证令牌来保护您的 POST 路由。
VaporCSRF 提供了一个中间件,可以为您检查令牌。 您可以使用以下方法将其应用于您的路由:
let csrfTokenPotectedRoutes = app.grouped(CSRFMiddleware())
如果您想控制何时验证 CSRF 令牌,您可以在您的路由处理程序中使用 try req.csrf.verifyToken()
手动进行验证。 例如:
app.post("myForm") { req -> EventLoopFuture<Response> in
try req.csrf.verifyToken()
// ...
}
默认情况下,VaporCSRF 在 POST body 中查找键为 csrfToken
的值。 您可以使用以下方法更改键:
app.csrf.setTokenContentKey("aDifferentKey")