55

これは教育プロジェクトであり、生産用ではありません。これの一部としてユーザー ログインを行うつもりはありませんでした。

ユーザーのログインなしで、CSRF トークンを使用して Django への POST 呼び出しを行うことはできますか? jQueryを使わずにこれを行うことはできますか? 私はここで深みがなく、確かにいくつかの概念を混同しています。

JavaScript 側では、このredux-csrfパッケージを見つけました。POSTAxios を使用してアクションと組み合わせる方法がわかりません。

export const addJob = (title, hourly, tax) => {
  console.log("Trying to addJob: ", title, hourly, tax)
  return (dispatch) => {
    dispatch(requestData("addJob"));
    return axios({
      method: 'post',
      url: "/api/jobs",
      data: {
        "title": title,
        "hourly_rate": hourly,
        "tax_rate": tax
      },
      responseType: 'json'
    })
      .then((response) => {
        dispatch(receiveData(response.data, "addJob"));
      })
      .catch((response) => {
        dispatch(receiveError(response.data, "addJob"));
      })
  }
};

Django側では、CSRFに関するこのドキュメントと、クラスベースのビューの一般的な操作に関するこのドキュメントを読みました。

これまでの私の見解は次のとおりです。

class JobsHandler(View):

    def get(self, request):
        with open('./data/jobs.json', 'r') as f:
            jobs = json.loads(f.read())

        return HttpResponse(json.dumps(jobs))

    def post(self, request):
        with open('./data/jobs.json', 'r') as f:
            jobs = json.loads(f.read())

        new_job = request.to_dict()
        id = new_job['title']
        jobs[id] = new_job

        with open('./data/jobs.json', 'w') as f:
            f.write(json.dumps(jobs, indent=4, separators=(',', ': ')))

        return HttpResponse(json.dumps(jobs[id]))

csrf_exempt今のところこれを心配する必要がないようにデコレータを使用してみましたが、それがどのように機能するかはわかりません。

{% csrf_token %}テンプレートに追加しました。

これは私のgetCookie方法です(Djangoのドキュメントから盗まれました):

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

Axios CSRF情報を変更する必要があることを読みました:

var axios = require("axios");
var axiosDefaults = require("axios/lib/defaults");

axiosDefaults.xsrfCookieName = "csrftoken"
axiosDefaults.xsrfHeaderName = "X-CSRFToken"

実際のトークン、呼び出しから取得した値をどこに貼り付けますgetCookie('csrftoken')か?

4

9 に答える 9

5

「簡単な方法」はほとんどうまくいきました。これはうまくいくようです:

import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "XCSRF-TOKEN";

そして、settings.py ファイルで:

CSRF_COOKIE_NAME = "XCSRF-TOKEN"
于 2017-03-23T19:39:09.133 に答える
1

yestema が言ったこと (および krescruz、cran_man、Dave Merwin などによって繰り返された) に加えて、以下も必要です。

axios.defaults.withCredentials = true
于 2019-02-17T14:13:50.803 に答える
1

私にとって、django は私が送信したヘッダーをリッスンしていませんでした。API にカールできましたが、axios でアクセスできませんでした。cors-headers パッケージをチェックしてください...これがあなたの新しい親友になるかもしれません。

django-cors-headers をインストールして修正しました

pip install django-cors-headers

そして追加

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

私のsettings.pyに

私も持っていました

ALLOWED_HOSTS = ['*']
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_EXPOSE_HEADERS = (
    'Access-Control-Allow-Origin: *',
)

私のsettings.pyでは、それはおそらくやり過ぎです

于 2018-04-28T03:13:48.593 に答える
1

Django が提供する CSRF トークンをすべての投稿リクエストに手動で追加することもできますが、それは面倒です。

Django ドキュメントから:

上記の方法 ( CSRF トークンを手動で設定する) は AJAX POST リクエストに使用できますが、いくつかの不都合があります: すべての POST リクエストで CSRF トークンを POST データとして渡すことを覚えておく必要があります。このため、別の方法があります。各 XMLHttpRequest で、カスタム X-CSRFToken ヘッダーを CSRF トークンの値に設定します。多くの JavaScript フレームワークには、すべてのリクエストでヘッダーを設定できるフックが用意されているため、これは簡単です。

ドキュメントには、CSRF トークン Cookie から CSRF トークンを取得し、それを AJAX リクエストのヘッダーに追加するために使用できるコードがあります。

于 2016-08-31T17:53:59.853 に答える