これは教育プロジェクトであり、生産用ではありません。これの一部としてユーザーログインをするつもりはありませんでした。
POST=への呼び出しをDjangoにユーザーログインせずにCSRFトークンで実行できますか?jQueryを使用せずにこれを実行できますか? 、そして確かにいくつかの概念を融合しています。
JavaScript側については、この redux-csrf パッケージが見つかりました。 Axiosを使用してPOST
アクションと組み合わせる方法がわかりません:
_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について、そして this をクラスベースのビューでの一般的な作業について読みました。
これまでの私の見解は次のとおりです。
_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= docs)から盗まれました):
_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')
の呼び出しから取得した値である実際のトークンをどこに貼り付けますか?
3つの方法があります。各axios呼び出しのヘッダーにトークンを手動で含めるか、各呼び出しでaxiosのxsrfHeaderName
を設定するか、デフォルトのxsrfHeaderName
を設定できます。
csrfToken
という変数にトークンの値が格納されているとしましょう。 axios呼び出しでヘッダーを設定します。
// ...
method: 'post',
url: '/api/data',
data: {...},
headers: {"X-CSRFToken": csrfToken},
// ...
xsrfHeaderName
を設定します。これを追加:
// ...
method: 'post',
url: '/api/data',
data: {...},
xsrfHeaderName: "X-CSRFToken",
// ...
次に、settings.py
ファイル、次の行を追加します。
CSRF_COOKIE_NAME = "XSRF-TOKEN"
各呼び出しでヘッダーを定義する代わりに、axiosのデフォルトヘッダーを設定できます。
Axiosをインポートして呼び出しを行うファイルで、インポートの下にこれを追加します。
axios.defaults.xsrfHeaderName = "X-CSRFToken";
次に、settings.py
ファイル、次の行を追加します。
CSRF_COOKIE_NAME = "XSRF-TOKEN"
Edit(2017年6月10日):ユーザー@yestemaは、Safariではわずかに異なる動作をすると言います[2]
編集(2019年4月17日):ユーザー@GregHolstによると、上記のSafariソリューションは機能しません彼のために。代わりに、MacOS Mojave上のSafari 12.1に対して上記のソリューション#3を使用しました。 (コメントから)
編集(2019年2月17日):設定が必要な場合もあります[3]:
axios.defaults.withCredentials = true
質問:この次のセクションは誰にとっても有用ですか?ソリューションを含めるだけでこの答えが改善されるのではないかと思っています。意見があれば教えてください。
混乱:
まず、 Django docs James Evans 参照 からのパッセージ全体:
...各XMLHttpRequestで、カスタムX-CSRFTokenヘッダーをCSRFトークンの値に設定します。多くのJavaScriptフレームワークには、リクエストごとにヘッダーを設定できるフックが用意されているため、これは簡単です。
最初のステップとして、CSRFトークン自体を取得する必要があります。トークンの推奨ソースはcsrftoken Cookieです。これは、上記で概説したようにビューのCSRF保護を有効にした場合に設定されます。
注意
CSRFトークンCookieはデフォルトでcsrftokenという名前になっていますが、CSRF_COOKIE_NAME設定を介してCookie名を制御できます。
CSRFヘッダー名はデフォルトでHTTP_X_CSRFTOKENですが、CSRF_HEADER_NAME設定を使用してカスタマイズできます。
これは Axios docs からのものです。 csrftoken
を含むCookieの名前とヘッダーの名前をここで設定したことを示しています。
// `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default
私の質問に示されているように、Cookieにはdocument.cookie
。私が持っている唯一のCookieは、Django=テンプレートに入れたCSRFトークンです。以下に例を示します。
csrftoken=5knNceCUi9nL669hGGsvCi93XfqNhwTwM9Pev7bLYBOMXGbHVrjitlkKi44CtpFU
これらのドキュメントには、混乱を招くような概念がいくつかあります。
csrftoken
であり、Cookieの等号の左側にあります。axios.defaults.xsrfCookieName = "XCSRF-TOKEN";
およびCSRF_COOKIE_NAME = "XCSRF-TOKEN"
動作しないApple Mac OS上のSafari
MAC Safariのソリューションは簡単です変更XCSRF-TOKEN
からcsrftoken
そのため、js-codeでは次のようになります。
import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
Settings.pyで:
CSRF_COOKIE_NAME = "csrftoken"
この設定は問題なく機能します Config axios CSRF Django
import axios from 'axios'
/**
* Config global for axios/Django
*/
axios.defaults.xsrfHeaderName = "X-CSRFToken"
axios.defaults.xsrfCookieName = 'csrftoken'
export default axios
「簡単な方法」はほとんど私のために働いた。これはうまくいくようです:
import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "XCSRF-TOKEN";
そして、settings.pyファイルで:
CSRF_COOKIE_NAME = "XCSRF-TOKEN"
Djangoが提供するCSRFトークンをすべての投稿リクエストに手動で追加できますが、それは面倒です。
Django docs から:
上記のメソッド(手動でCSRFトークンを設定する)はAJAX POSTリクエストに使用できますが、いくつかの不便:POSTリクエストごとにPOSTデータとしてCSRFトークンを渡すことを忘れないでください。このため、別の方法があります。各XMLHttpRequestで、カスタムX-CSRFTokenヘッダーをCSRFトークンの値に設定します。多くのJavaScriptフレームワークには、リクエストごとにヘッダーを設定できるフックが用意されているため、これは簡単です。
ドキュメントには、CSRFトークンCookieからCSRFトークンを取得し、AJAXリクエストのヘッダーに追加するために使用できるコードがあります。
実際にこれを行うには本当に簡単な方法があります。
追加 axios.defaults.xsrfHeaderName = "X-CSRFToken";
をアプリの構成に設定してからCSRF_COOKIE_NAME = "XSRF-TOKEN"
はsettings.pyファイルにあります。魅力のように機能します。
私にとっては、Djangoは送信したヘッダーをリッスンしていませんでした。APIにカールできましたが、axiosでアクセスできませんでした。 cors-headers package ...それはあなたの新しい親友かもしれません。
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でそれはおそらくやり過ぎです
Yestemaが言ったこと(およびkrescruz、cran_man、Dave Merwin et。alによってエコーされたもの)に加えて、以下も必要です。
axios.defaults.withCredentials = true