React/Redux 应用程序在 cookie 中保护 JWT 的最佳方法是什么?

What is the optimal way to secure JWT in cookies for a React/Redux application?

现在我正在开发一个 React/Redux 全栈应用程序,我正在设置 JWT 身份验证并通过 cookie 传递 JWT。我有几个关于处理服务器生成的 CSRF 令牌的问题。

1) 在服务器端设置 CSRF 令牌后,它会传递给客户端吗?它究竟是如何通过的? (我已经看到它作为 object 传入的示例,但我发现的那些没有得到很好的解释或只是稀缺)

server.js

// config csrf in server
app.use(csrf({
  cookie: {
    key: '_csrf',
    secure: true,
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 86400
  }
}))

// Hits my api routes, and if these arent hit, the index.html file is rendered
app.use(routes)

// Route used to fetch the index html file
app.get('*', (req, res) => {
  let csrfToken = req.csrfToken()
  console.log(csrfToken) // This doesnt console log anything on the server side
  res.sendFile(path.join(__dirname, "./client/build/index.html"), {
    _csrf: csrfToken
  })
})

2) 一旦设置了CSRF token,它是否应该存储在应用程序的状态(Redux store)中以进行持久存储?或者这是不必要的吗?

3) 在客户端,当我准备通过 POST 请求向路由提交数据时,如果我理解正确的话,您必须将输入隐藏字段包含在 csrf 变量中像这样:

<input type="hidden" name="_csrf" value=csrfToken/>

因此,当您提交表单时,您将包含该输入,然后在 post 请求(假设是 fetch 或 axios)中,您将设置 headers 以包含该 csrf 令牌,这样服务器就可以将它与客户端提交给路由的令牌进行比较,我理解正确吗?

谢谢!

None 您所问的具体问题与 React 或 Redux 相关。这是关于与 HTTP 服务器的请求/响应交换。

使用 CSRF 中间件时,它会根据请求自动提供 CSRF 令牌作为 session cookie,您需要在进一步请求时将其提供回服务器。

1) CSRF 令牌通常由服务器设置在 cookie 中,或者设置为 HTML 中的元标记。此代码是根据对服务器的 HTTP 请求唯一生成的。应用程序负责读取 cookie/meta 标记,然后将其发送回服务器以供将来请求。一种可能的方式是 header:‘X-csrf-token’ (https://en.m.wikipedia.org/wiki/Cross-site_request_forgery)

2) 在某些情况下是不必要的:但这只是因为如果服务器发送 cookie header 响应,那么您的浏览器将始终存储该 cookie,除非您关闭了 cookie。当向服务器发送请求时,您需要检索该 cookie 并将其作为上面的 header

发送

3) 我建议您阅读 express CSRF 中间件的自述文件 (https://github.com/expressjs/csurf/blob/master/README.md),尤其是关于中间件如何在响应或进一步请求中查找 CSRF 令牌的部分:

The default value is a function that reads the token from the following locations, in order: • req.body._csrf - typically generated by the body-parser module. • req.query._csrf - a built-in from Express.js to read from the URL query string. • req.headers['csrf-token'] - the CSRF-Token HTTP request header. • req.headers['xsrf-token'] - the XSRF-Token HTTP request header. • req.headers['x-csrf-token'] - the X-CSRF-Token HTTP request header. • req.headers['x-xsrf-token'] - the X-XSRF-Token HTTP request header.

如您所见 - 如何将其提供回服务器由您决定 - 大多数人选择 header,但它可以作为 body 或获取请求查询字符串.