簡體   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