Vapor CSRF

Vapor CSRF

Language Language Build Status Code Coverage MIT License

一个简单的库,用于保护 POST 请求免受 CSRF(跨站请求伪造)攻击。

什么是 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)

有关会话的更多信息,请参阅文档

GET 路由

在可能返回您想要保护的 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 路由

您可以使用中间件或手动验证令牌来保护您的 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")