我必须在 React SPA 中使用 csrf 保护吗?
Posted
技术标签:
【中文标题】我必须在 React SPA 中使用 csrf 保护吗?【英文标题】:Do i have to use csrf protection in React SPA? 【发布时间】:2019-07-01 10:42:48 【问题描述】:我使用 React 单页应用程序作为客户端或创建 React 应用程序 (CRA)。
在我的后端我使用 Node.js 和 Express。
要获取数据或存储,我需要从客户端调用 API 到后端。
实际上我已经看到有几个中间件,例如:- Express CSURF
但老实说,我不明白如何在每次请求时向客户端发送 CSRF 令牌。我已经尝试了几次,通过将 CSRF 插入 cookie 然后将其带到客户端。但是当第一个请求或新 cookie 被存储时,我得到错误Invalid CSRF Token
。
即使我这样做了:
app.use(session(
genid: function (req)
return uuidv4() // use UUIDs for session IDs
,
name:keys.session.name,
secret: keys.session.secret,
resave: false,
saveUninitialized: true,
rolling:true,
cookie:
secure: false,
httpOnly: true,
maxAge:keys.session.maxAge, // satu hari,
sameSite:true,
));
app.use(passport.session());
app.use(cookieParser());
app.use(csrf( cookie: false ));
app.use((req,res,next)=>
res.cookie('CSRF_token', req.csrfToken(), sameSite: true );
)
这意味着 CSRF_token cookie 将更改每个请求。但我只设置了一次:axios.defaults.headers.common['csrf-token'] = csrf;
并且结果仍然有效,但应该不起作用。
那么我需要 CSRF 吗?或如何在 react SPA 上配置正确的。
【问题讨论】:
我很想知道这个问题的答案 【参考方案1】:那么我需要 CSRF 吗?
如此处所述:Am I under risk of CSRF attacks in a POST form that doesn't require the user to be logged in? 我认为您仍然应该设置它。
至于为什么它不适合你,我认为是因为标题名称。你可以查看CSURF checks by default是什么。
默认值是从以下位置读取令牌的函数,按顺序:
req.body._csrf - 通常由 body-parser 模块生成。 req.query._csrf - Express.js 的内置函数,用于从 URL 查询字符串中读取。 req.headers['csrf-token'] - CSRF-Token HTTP 请求标头。 req.headers['xsrf-token'] - XSRF-Token HTTP 请求标头。 req.headers['x-csrf-token'] - X-CSRF-Token HTTP 请求标头。 req.headers['x-xsrf-token'] - X-XSRF-Token HTTP 请求标头。
按照 CSURF 检查的内容,您有多种选择,请查看 axios, it seems to have a couple options for setting xsrf cookie and header names。
...
// `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default
...
例如为了使用axios默认自带的X-XSRF-TOKEN
header key,我在我的App.js文件中使用了如下方法:
componentDidMount()
axios.get(`/api/csrf`) // Send get request to get CSRF token once site is visited.
.then(res =>
axios.defaults.headers.post['X-XSRF-TOKEN'] = res.data; // Set it in header for the rest of the axios requests.
)
但是,您可以使用表单隐藏输入或您喜欢的任何其他方法。您可以阅读更多关于为什么将它们放在 cookie 中的常见原因here。
我不确定您为您的客户使用的是什么,但如果您使用的是 Redux,您可能会向 here 寻求帮助。如果还是不行,你可以谷歌其他方法。
【讨论】:
这有多安全?通过端点请求 csrf 令牌。这不会破坏 csrf 令牌的目的吗? @alex067 理想情况下,您将有一个前端服务器将令牌注入您的前端应用程序。从某种意义上说,这不是最好的解决方案,您是正确的,但是如果没有前端服务器,我无法找到缓解这种情况的方法。否则,您可以在 jwt cookie 中对令牌进行签名,以确保它没有被替换。 我花了一整天的时间寻找解决方案,但我做不到。似乎没有人知道如何正确地做到这一点。以上是关于我必须在 React SPA 中使用 csrf 保护吗?的主要内容,如果未能解决你的问题,请参考以下文章
SPA 使用的经过身份验证的 Rest API:如何获取用于登录和注册表单的 CSRF 令牌?
Laravel SPA 是不是仍应使用 CSRF 令牌来保证安全?
使用双重提交 cookie 的角度 SPA 中的 CSRF 保护