Fetch, set-cookies and csrf (Cross-Site Request Forgery)

13 浏览
0 Comments

Fetch, set-cookies and csrf (Cross-Site Request Forgery)

我在我的应用程序中使用了Isomorphic fetch,并且在处理CSRF时遇到了一些问题。

实际上,我有一个后端,在set-cookies属性中向我发送了一个CSRF-TOKEN:

enter image description here

我在某个地方读到过,直接在我的代码中访问这种cookie是不可能的,或者是一种不好的做法。

因此,我尝试使用fetch请求的credentials属性来做些什么:

const headers = new Headers({
            'Content-Type': 'x-www-form-urlencoded'
        });
        return this.fetcher(url, {
            method: 'POST',
            headers,
            credentials: 'include',
            body: JSON.stringify({
                email: 'mail@mail.fr',
                password: 'password'
            })
        });

这样,我可以将我的CSRF cookie发送回服务器以满足我的需求(这是一个不同的请求,因为它不是同一个请求):

enter image description here

我的问题

我的问题是,我的后端需要接收一个x-csrf-token头,所以我不能将其设置为我的POST请求。

我需要什么

我该如何将set-cookies: CSRF-TOKEN的值放入下一个请求的x-csrf-token头中?

0
0 Comments

Fetch, set-cookies和CSRF问题的出现原因和解决方法

当使用Fetch API进行网络请求时,有时会遇到一些问题,这些问题涉及到设置cookies和CSRF(Cross-Site Request Forgery)令牌。这些问题可能会导致请求无法成功发送或者被服务器拒绝。

原因:

1. Cookies的问题:在使用Fetch API发送请求时,默认情况下不会包含任何cookies。这是因为Fetch API的设计初衷是通过现代的Web标准来处理网络请求,而不是通过传统的cookies机制。因此,如果服务器要求在请求中携带cookies,可能会导致请求失败。

2. CSRF令牌的问题:CSRF是一种跨站请求伪造攻击,它利用了Web应用程序中的漏洞,使攻击者能够以受害者的身份执行非法操作。为了防止CSRF攻击,Web应用程序通常会在每个请求中包含一个CSRF令牌。然而,使用Fetch API时,默认情况下不会自动发送CSRF令牌,这可能导致请求被服务器拒绝。

解决方法:

1. 设置cookies:要在Fetch请求中携带cookies,可以使用Fetch API提供的credentials属性来进行配置。credentials属性有三个可能的值:omit、same-origin和include。默认值是omit,表示不包含任何cookies。如果要发送请求时包含cookies,可以将credentials属性设置为include。

fetch(url, {
  credentials: 'include',
  // 其他请求参数
})

2. 设置CSRF令牌:要在Fetch请求中包含CSRF令牌,可以通过设置请求头来实现。在请求头中添加X-CSRFToken字段,并将其值设置为CSRF令牌的值。具体的设置方法取决于服务器的要求,以Django为例,可以在Fetch请求的headers中添加X-CSRFToken字段,并将其值设置为获取CSRF令牌的方法。

fetch(url, {
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8',
    'X-CSRFToken': get_token
  },
  // 其他请求参数
})

通过以上的解决方法,可以解决使用Fetch API时遇到的cookies和CSRF问题,确保请求能够成功发送并得到正确的响应。

0
0 Comments

在这种情况下,您应该从CSRF-TOKEN cookie中读取数据。否则,它将被标记为HttpOnly,例如JSESSIONID。后者意味着您无法从网页中访问它,只能自动发送回服务器。通常从cookie中读取CSRF令牌是没有问题的。请参考这个很好的讨论:为什么通常将CSRF预防令牌放在cookie中?

您可以使用以下代码读取cookie(不包括HttpOnly):

function getCookie(name) {
  if (!document.cookie) {
    return null;
  }
  const xsrfCookies = document.cookie.split(';')
    .map(c => c.trim())
    .filter(c => c.startsWith(name + '='));
  if (xsrfCookies.length === 0) {
    return null;
  }
  return decodeURIComponent(xsrfCookies[0].split('=')[1]);
}

因此,fetch调用可能如下所示:

const csrfToken = getCookie('CSRF-TOKEN');
const headers = new Headers({
        'Content-Type': 'x-www-form-urlencoded',
        'X-CSRF-TOKEN': csrfToken
    });
    return this.fetcher(url, {
        method: 'POST',
        headers,
        credentials: 'include',
        body: JSON.stringify({
            email: 'test.com',
            password: 'password'
        })
    });

请修复打字错误:X-XSRF-TOKEN应该是X-CSRF-TOKEN,标头名称取决于服务器端,实际上可以是X-CSRF-TOKEN或X-XSRF-TOKEN,或者有一些自定义名称。

0