繁体   English   中英

Django React CSRF问题

[英]Django React CSRF Issues

使用Django作为后端和React作为前端构建我的第一个应用程序。

在本地,我分别在端口8000和3000上运行。

我在网上找到了一小段代码,以帮助我测试我的CSRF和CORS策略是否设置正确:

const API_HOST = 'http://localhost:8000';

let _csrfToken = null;

async function getCsrfToken() {
  if (_csrfToken === null) {
    const response = await fetch(`${API_HOST}/csrf/`, {
      credentials: 'include',
    });
    const data = await response.json();
    _csrfToken = data.csrfToken;
  }
  return _csrfToken;
}

async function testRequest(method) {
  const response = await fetch(`${API_HOST}/ping/`, {
    method: method,
    headers: (
      method === 'POST'
        ? {'X-CSRFToken': await getCsrfToken()}
        : {}
    ),
    credentials: 'include',
  });
  const data = await response.json();
  return data.result;
}


class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      testGet: 'KO',
      testPost: 'KO',
    };
  }

  async componentDidMount() {
    this.setState({
      testGet: await testRequest('GET'),
      testPost: await testRequest('POST'),
    });
  }

  render() {
    return (
      <div>
        <p>Test GET request: {this.state.testGet}</p>
        <p>Test POST request: {this.state.testPost}</p>
      </div>
    );
  }
}

export default App;

编辑澄清:远程GET请求通过,只有POST失败

当我在本地运行此代码时,我得到正确的响应,即当响应返回有效时,“KO”变为“OK”。

这只适用于我的机器。 如果我尝试从网络中的任何其他计算机访问它,我会收到以下错误:

403禁止

Django的调试原因是“CSRF cookie未设置”。

但是,在控制台中,我可以看到标题确实正在发送X-CSRFToken。

我有一个我的后端的“实时”版本,我也尝试使用与本地相同的结果。

如果我从我自己的计算机上尝试它,我只能得到一个成功的测试。

Django设置:

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = ['localhost:3000', 'My_Public_Ip:3000']

我怀疑我的问题是在白名单中的某个地方,但我现在不知道发现它是什么。

如果有人可以帮我理解发生的事情,如果他们没有答案,那可能会引发“aha”时刻。

您是否尝试从实际cookie中获取CSRF令牌而不是向服务器发出请求? 因为您现在正在做的是每次尝试获取任何内容时都获取CSRF令牌。

在JavaScript中尝试以下内容:

import Cookies from 'js-cookie;

async function testRequest(method) {
    const headers = {};
    const csrftoken = Cookies.get('csrftoken'); // or the value from settings.CSRF_COOKIE_NAME
    if (csrftoken) {
        headers['X-CSRFTOKEN'] = csrftoken;
    }
    const response = await fetch(`${API_HOST}/ping/`, {
        method,
        headers,
        credentials: 'include',
    });
    const data = await response.json();
    return data.result;
}

除了@ tgdn建议从cookie中获取令牌之外,我还建议检查CSRF的 会话和Cookie的SameSite策略设置,因为将其设置为StrictLax也会禁止在跨域请求中发送cookie(可能导致失去你的会话/被注销等...)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM