获取、设置 cookie 和 csrf

Posted

技术标签:

【中文标题】获取、设置 cookie 和 csrf【英文标题】:Fetch, set-cookies and csrf 【发布时间】:2017-04-15 01:57:27 【问题描述】:

我在我的应用程序中使用 Isomorphic fetch,但在处理 CSRF 时遇到了一些麻烦。

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

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

这样,我尝试使用获取请求的凭据属性来做一些事情:

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 发送回我的服务器以满足我的需求(这是一个不同的,因为它不是同一个请求):

我的问题

我的问题是我的后端需要接收 x-csrf-token 标头,因此我无法将其设置为我的 POST 请求。

我需要什么

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

【问题讨论】:

【参考方案1】:

在您的场景中,您应该从 CSRF-TOKEN cookie 中读取数据。否则它将被标记为 HttpOnly 为 JSESSIONID。后者意味着您无法从网页访问它,而只能自动发送回服务器。

一般来说,从 cookie 中读取 CSRF 令牌没有任何问题。请查看这个很好的讨论:Why is it common to put CSRF prevention tokens in cookies?

您可以使用以下代码读取您的 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@example.com',
            password: 'password'
        )
    );

【讨论】:

请修正错字:X-XSRF-TOKEN 应该是 X-CSRF-TOKEN @Lunokhod,标题名称取决于您的服务器端,实际上可以是 X-CSRF-TOKEN 或 X-XSRF-TOKEN 或有一些自定义名称【参考方案2】:

是的,标题名称取决于您的服务器。例如使用 fetch 设置 CSRF 令牌的 django 用例是这样的:

  headers: 
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8',
    'X-CSRFToken': get_token
  ,

【讨论】:

以上是关于获取、设置 cookie 和 csrf的主要内容,如果未能解决你的问题,请参考以下文章

带有 React 的 Django DRF:如何获取 CSRF cookie?

Jwt 中 token应该存储到哪里?

71. Django 前后端分离csrf token获取方式

Django设置cookie中的csrftoken

Django 设置 cookie 中的 csrftoken

防止跨站攻击——CSRFToken