我使用React Single Page Application作为客户端或创建React App(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上配置正确的服务器。
答案 0 :(得分:0)
那我需要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
标头键,我在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寻求帮助。如果不起作用,您可以使用Google其他方法。