我必须在React SPA中使用csrf保护吗?

时间:2019-02-07 10:29:41

标签: node.js reactjs express csrf

我使用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上配置正确的服务器。

1 个答案:

答案 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其他方法。