私はLaravel 5のアプリで作業しています。すべてのPOST要求に対してデフォルトでCSRF保護が有効になっています。それ。
簡単な$.post()
リクエストを作成しているときに、必要なフォーム入力_'Illuminate\Session\TokenMismatchException'
_がPOST=データから欠落しているため、__token
_エラーを受け取りました。問題の$ .postリクエストの例:
_var userID = $("#userID").val();
$.post('/admin/users/delete-user', {id:userID}, function() {
// User deleted
});
_
CSRFトークンをヘッダーのメタフィールドとして保存し、次を使用して簡単にアクセスできます。
_var csrf_token = $('meta[name="csrf-token"]').attr('content');
_
すべての発信$.post()
リクエストでJSONデータにこれを追加することは可能ですか?ヘッダーを使用してみましたが、Laravelはヘッダーを認識していないようです-
_var csrf_token = $('meta[name="csrf-token"]').attr('content');
alert(csrf_token);
$.ajaxPrefilter(function(options, originalOptions, jqXHR){
if (options['type'].toLowerCase() === "post") {
jqXHR.setRequestHeader('X-CSRFToken', csrf_token);
}
});
_
あなたの$.ajaxPrefilter
アプローチは良い方法です。ただし、ヘッダーを追加する必要はありません。プロパティをdata
文字列に追加するだけです。
データは$.post
の2番目の引数として提供され、プレフィルターがdata
オプションにアクセスする前にクエリ文字列(id=foo&bar=baz&...
)としてフォーマットされます。したがって、クエリ文字列に独自のフィールドを追加する必要があります。
var csrf_token = $('meta[name="csrf-token"]').attr('content');
$.ajaxPrefilter(function(options, originalOptions, jqXHR){
if (options.type.toLowerCase() === "post") {
// initialize `data` to empty string if it does not exist
options.data = options.data || "";
// add leading ampersand if `data` is non-empty
options.data += options.data?"&":"";
// add _token entry
options.data += "_token=" + encodeURIComponent(csrf_token);
}
});
これにより、id=userID
がid=userID&_token=csrf_token
に変わります。
From Laravel documentation:
たとえば、トークンを「メタ」タグに保存できます。
メタタグを作成したら、jQueryなどのライブラリに、すべてのリクエストヘッダーにトークンを追加するように指示できます。これにより、AJAXベースのアプリケーションにシンプルで便利なCSRF保護が提供されます。
$ .ajaxSetup({headers:{'X-CSRF-TOKEN':$( 'meta [name = "csrf-token"]')。attr( 'content')}});
たとえば、次のようなリクエストを行うことができます。
ビューにこのメタタグを追加します。
<meta name="csrf-token" content="{{ csrf_token() }}">
これは、Laravel(id = "some-id"の要素をクリックするとリクエストを送信し、id = "の要素で応答を確認できるスクリプト例です。結果"):
<script type="text/javascript">
$(document).ready(function(){
$.ajaxSetup({
headers:
{ 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
});
$("#some-id").on("click", function () {
var request;
request = $.ajax({
url: "/your/url",
method: "POST",
data:
{
a: 'something',
b: 'something else',
},
datatype: "json"
});
request.done(function(msg) {
$("#result").html(msg);
});
request.fail(function(jqXHR, textStatus) {
$("#result").html("Request failed: " + textStatus);
});
});
});
</script>
一般的に、Kornelが提案したコンセプトに同意しますが、1つだけあります。
はい、Laravelの_$.ajaxSetup
_を使用するようにアドバイスしていますが、この方法は後続のすべてのAjaxリクエストに影響するためお勧めしません。各リクエストにajax設定を設定する方がより正確です。ものをリセットできますが:
関数を使用する後続のすべてのAjax呼び出しは、$。ajaxSetup()の次の呼び出しまで、個々の呼び出しによってオーバーライドされない限り、新しい設定を使用します
$.ajax()
を使用する場合は、data
プロパティまたはheaders
を使用する方が便利です。 Laravelは、CSRFトークンを要求パラメーターまたはヘッダーの両方として許可します。
最初に、次のメタタグをビューに追加します
_<meta name="csrf-token" content="{{ csrf_token() }}">
_
そして、いずれかの方法でajaxリクエストを作成します。
_$.ajax({
url: "/your/url",
method: "POST",
data:
{
a: 'something',
b: 'something else',
_token: $('meta[name="csrf-token"]').attr('content')
},
datatype: "json"
});
_
OR
_$.ajax({
url: "/your/url",
method: "POST",
data:
{
a: 'something',
b: 'something else',
},
headers:
{
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
datatype: "json"
});
_
CSRFに関するDjangoのドキュメント は、重要なすべてのリクエストタイプに適切なヘッダーを自動的に追加するためのajaxSetup
を持つニースコードスニペットを提供します。
function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
これを行うにはもっと簡単な方法があります。送信する前にデータをシリアル化できます
<form method="post" id="formData">
<input type="text" name="name" >
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" id="sub" class="btn btn-default" value="Submit" />
</form>
<script>
$(document).on('submit', '#formData', function (event) {
event.preventDefault();
var formData = $('#formData').serialize();
$.ajax({
url: url,
type: "POST",
data : formData,
success: function (result) {
console.log(result);
}
});
});
});
</script>
名前がattrのすべてのものがクエリに入力され、送信されます
上記の解決策もうまく機能しない可能性があると思います。行うとき:
var x;
x + ""
// "undefined" + empty string coerces value to string
「undefined_token = xxx」のようなデータを取得します
たとえば、上記のソリューションをlaravelの削除に使用する場合、次のように確認する必要があります。
if (typeof options.data === "undefined")
options.data = "";
else
options.data += "&";
options.data = "_token=" + csrf_token;