program story

Ajax POST 요청에 대한 Laravel csrf 토큰 불일치

inputbox 2020. 11. 22. 19:25
반응형

Ajax POST 요청에 대한 Laravel csrf 토큰 불일치


ajax를 통해 데이터베이스에서 데이터를 삭제하려고합니다.

HTML :

@foreach($a as $lis)
  //some code
  <a href="#" class="delteadd" id="{{$lis['id']}}">Delete</a>
  //click action perform on this link                  
@endforeach

내 아약스 코드 :

$('body').on('click', '.delteadd', function (e) {
e.preventDefault();
//alert('am i here');
if (confirm('Are you sure you want to Delete Ad ?')) {
    var id = $(this).attr('id');
    $.ajax({
        method: "POST",
        url: "{{url()}}/delteadd",
        }).done(function( msg ) {
        if(msg.error == 0){
            //$('.sucess-status-update').html(msg.message);
            alert(msg.message);
        }else{
            alert(msg.message);
            //$('.error-favourite-message').html(msg.message);
        }
    });
} else {
    return false;
}
});

이것은 데이터베이스에서 데이터를 가져 오는 내 쿼리입니다.

$a = Test::with('hitsCount')->where('userid', $id)->get()->toArray();

하지만 삭제되지 않은 링크 데이터 삭제를 클릭하면 csrf_token 불일치가 표시됩니다 ...


ajax 요청에 데이터 를 추가해야합니다 . 그렇게 될 수 있기를 바랍니다.

data: {
        "_token": "{{ csrf_token() }}",
        "id": id
        }

"X-CSRF-TOKEN"문제를 해결하는 가장 좋은 방법은 기본 레이아웃에 다음 코드를 추가하고 정상적으로 ajax 호출을 계속하는 것입니다.

헤더에서

<meta name="csrf-token" content="{{ csrf_token() }}" />

스크립트에서

<script type="text/javascript">
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
</script>

토큰을 형식에 넣고이 토큰을 id

<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">

그리고 JQUery :

var data = {
        "_token": $('#token').val()
    };

이렇게하면 JS가 블레이드 파일에있을 필요가 없습니다.


방금 headers:ajax 호출에 추가 했습니다.

  headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},

보기 :

<div id = 'msg'>
     This message will be replaced using Ajax. Click the button to replace the message.
</div>

{{ Form::submit('Change', array('id' => 'ajax')) }}

아약스 기능 :

<script>
 $(document).ready(function() {
    $(document).on('click', '#ajax', function () {
      $.ajax({
         type:'POST',
         url:'/ajax',
         headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
         success:function(data){
            $("#msg").html(data.msg);
         }
      });
    });
});
</script>

컨트롤러에서 :

public function call(){
    $msg = "This is a simple message.";
    return response()->json(array('msg'=> $msg), 200);
}

route.php에서

Route::post('ajax', 'AjaxController@call');

템플릿 파일을 사용하는 경우 meta태그가 포함 된 헤드 section(또는 이름이 무엇이든)에 meta태그 를 넣을 수 있습니다 .

@section('head')
<meta name="csrf_token" content="{{ csrf_token() }}" />
@endsection

다음으로 headers속성을 귀하 속성 에 넣어야 합니다 ajax(제 예에서는 datatable서버 측 처리와 함께 사용 하고 있습니다 :

"headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')}

다음은 전체 datatableajax 예제입니다.

$('#datatable_users').DataTable({
        "responsive": true,
        "serverSide": true,
        "processing": true,
        "paging": true,
        "searching": { "regex": true },
        "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
        "pageLength": 10,
        "ajax": {
            "type": "POST",
            "headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')},
            "url": "/getUsers",
            "dataType": "json",
            "contentType": 'application/json; charset=utf-8',
            "data": function (data) {
                console.log(data);
            },
            "complete": function(response) {
                console.log(response);
           }
        }
    });

이렇게하면 요청 을 받아야 200 status합니다 ajax.


편의를 위해 설정된 X-XSRF-TOKEN 쿠키가 있습니다. Angular 및 기타와 같은 프레임 워크는 기본적으로 설정합니다. 문서 https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token 에서 확인하십시오 .

가장 좋은 방법은 쿠키가 비활성화 된 경우 메타를 사용하는 것입니다.

    var xsrfToken = decodeURIComponent(readCookie('XSRF-TOKEN'));
    if (xsrfToken) {
        $.ajaxSetup({
            headers: {
                'X-XSRF-TOKEN': xsrfToken
            }
        });
    } else console.error('....');

여기에 권장되는 메타 방식이 있습니다 (어떤 방식 으로든 필드를 넣을 수 있지만 메타는 조용합니다) :

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});   

의 사용을 참고 decodeURIComponent()쿠키를 저장하는 데 사용되는 URI 형식에서 그것의 디코딩. [그렇지 않으면 laravel에서 잘못된 페이로드 예외가 발생합니다].

다음은 확인할 문서의 csrf 쿠키에 대한 섹션입니다. https://laravel.com/docs/5.7/csrf#csrf-x-csrf-token

또한 laravel (bootstrap.js)이 기본적으로 axios에 대해 설정하는 방법도 있습니다.

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
} 

당신은 확인할 수 있습니다 resources/js/bootstrap.js.

그리고 여기 쿠키 기능을 읽으십시오.

   function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
       }
        return null;
    }

jQuery를 사용하여 AJAX 게시물을 보내는 경우 다음 코드를 모든보기에 추가하십시오.

$( document ).on( 'ajaxSend', addLaravelCSRF );

function addLaravelCSRF( event, jqxhr, settings ) {
    jqxhr.setRequestHeader( 'X-XSRF-TOKEN', getCookie( 'XSRF-TOKEN' ) );
}

function getCookie(name) {
    function escape(s) { return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1'); };
    var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
    return match ? match[1] : null;
}

Laravel은 모든 요청에 ​​XSRF 쿠키를 추가하고 제출 직전에 모든 AJAX 요청에 자동으로 추가합니다.

동일한 작업을 수행하는 다른 함수 또는 jQuery 플러그인이있는 경우 getCookie 함수를 대체 할 수 있습니다.


Add an id to the meta element that holds the token

<meta name="csrf-token" id="csrf-token" content="{{ csrf_token() }}">

And then you can get it in your Javascript

$.ajax({
  url : "your_url",
  method:"post",
  data : {
    "_token": $('#csrf-token')[0].content  //pass the CSRF_TOKEN()
  },  
  ...
});

I actually had this error and could not find a solution. I actually ended up not doing an ajax request. I don't know if this issue was due to this being sub domain on my server or what. Here's my jquery.

            $('#deleteMeal').click(function(event) {
                var theId = $(event.currentTarget).attr("data-mealId");
                  $(function() {
                    $( "#filler" ).dialog({
                      resizable: false,
                      height:140,
                      modal: true,
                      buttons: {
                      "Are you sure you want to delete this Meal? Doing so will also delete this meal from other users Saved Meals.": function() {
                           $('#deleteMealLink').click();
//                         jQuery.ajax({
//                              url : 'http://www.mealog.com/mealtrist/meals/delete/' + theId,
//                              type : 'POST',
//                              success : function( response ) {
//                                  $("#container").replaceWith("<h1 style='color:red'>Your Meal Has Been Deleted</h1>");
//                              }
//                          });
                        // similar behavior as clicking on a link
                           window.location.href = 'http://www.mealog.com/mealtrist/meals/delete/' + theId;
                          $( this ).dialog( "close" );
                        },
                        Cancel: function() {
                          $( this ).dialog( "close" );
                        }
                      }
                    });
                  });
                });

So I actually set up an anchor to go to my API rather than doing a post request, which is what I figure most applications do.

  <p><a href="http://<?php echo $domain; ?>/mealtrist/meals/delete/{{ $meal->id }}" id="deleteMealLink" data-mealId="{{$meal->id}}" ></a></p>

You should include a hidden CSRF (cross site request forgery) token field in the form so that the CSRF protection middleware can validate the request.

Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually makin gthe requests to the application.

So when doing ajax requests, you'll need to pass the csrf token via data parameter. Here's the sample code.

var request = $.ajax({
    url : "http://localhost/some/action",
    method:"post",
    data : {"_token":"{{ csrf_token() }}"}  //pass the CSRF_TOKEN()
  });

For Laravel 5.8, setting the csrf meta tag for your layout and setting the request header for csrf in ajax settings won't work if you are using ajax to submit a form that already includes a _token input field generated by the Laravel blade templating engine.

You must include the already generated csrf token from the form with your ajax request because the server would be expecting it and not the one in your meta tag.

For instance, this is how the _token input field generated by Blade looks like:

<form>
    <input name="_token" type="hidden" value="cf54ty6y7yuuyyygytfggfd56667DfrSH8i">
    <input name="my_data" type="text" value="">
    <!-- other input fields -->
</form>

You then submit your form with ajax like this:

<script> 
    $(document).ready(function() { 
        let token = $('form').find('input[name="_token"]').val();
        let myData = $('form').find('input[name="my_data"]').val();
        $('form').submit(function() { 
            $.ajax({ 
                type:'POST', 
                url:'/ajax', 
                data: {_token: token, my_data: myData}
                // headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}, // unnecessary 
                // other ajax settings
            }); 
            return false;
        }); 
    }); 
</script>

The csrf token in the meta header is only useful when you are submitting a form without a Blade generated _token input field.

참고URL : https://stackoverflow.com/questions/32738763/laravel-csrf-token-mismatch-for-ajax-post-request

반응형