Я создаю плагин для определенного приложения в c #, который должен взаимодействовать с интерфейсом отдыха Django.
Как вы знаете, Django использует токены CSRF для дополнительной безопасности.
У меня проблема при выполнении вызова POST / PUT для Django. Вызов всегда будет возвращать «CSRF Failed: токен CSRF отсутствует или неверен».
Я протестировал вызов в браузере (веб-интерфейс также может редактировать данные и будет вызывать тот же запрос PUT), и, к моему удивлению, в заголовке X-CSRFToken используется другое значение токена csrf, чем значение, сохраненное в cookie , Должен ли заголовок X-CSRFToken использовать только что созданный токен? Значение X-CSRFToken никогда не используется снова после этого вызова (старое значение csrftoken все еще используется для всех последующих вызовов ...).
Очевидно, я также читал документы Django относительно токенов csrf. Хотя я думаю, что понимаю, как это работает, я не понимаю, почему новый токен используется для POST / PUT. Есть много примеров, которые не имеют смысла для использования в моем плагине C #.
Что я делаю, прежде чем делать PUT:
- Получите токен CSRF, запросив страницу входа, содержащую в своем теле csrfmiddlewaretoken.
- Сохранить файл cookie "csrftoken" с токеном в качестве значения (К сожалению, файл cookie не сохраняется автоматически)
- Войти в систему (POST), используя учетные данные (csrfmiddlewaretoken = {token} также передается в качестве параметра)
После выполнения вышеописанного все вызовы GET работают отлично.
Проблема возникает, когда я пытаюсь сделать POST или PUT.
Это мой код PUT, игнорирующий генерацию json и url, поскольку это не проблема:
// The _csrftoken used here, is the one I fetch at the beginning
Client().DefaultRequestHeaders.Add("X-CSRFToken", _csrftoken);
// The content is json
var response = Client().PutAsync(url, content).GetAwaiter().GetResult();
// The returned content is: {"detail":"CSRF Failed: CSRF token missing or incorrect."}"
var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
// 403 is returned
if (response.IsSuccessStatusCode) { ... }
Код выше выполнен со следующим состоянием:
- Пользователь вошел в систему (сессионный cookie доступен)
- токен csrf доступен при входе в систему (также доступен файл cookie csrftoken)
Что я пытался решить проблему:
- Передать csrfmiddlewaretoken = {token} в качестве параметра
- сохранить файл cookie X-CSRFToken
- Использование X-CSRFToken, который я скопировал из PUT, выполненного в веб-интерфейсе
- Попытка HttpWebRequest вместо PutAsync
- Реплицируйте PUT из веб-интерфейса, скопировав все заголовки / параметры / файлы cookie из PUT, выполненного в веб-интерфейсе
- ...
Может кто-нибудь помочь мне понять, что я делаю неправильно?
Большое спасибо за любую помощь, которую вы можете мне оказать.