Welcome Guest, Not a member yet? Register   Sign In
CI3 file upload via ajax with csrf
#1

(This post was last modified: 06-03-2020, 07:45 AM by Goddard.)

How can I include the csrf token with the file upload?  It appears using the new Form() functions with the upload data doesn't work.  I see the csrf token in the params but it is always saying Forbidden.  If I disable CSRF token security then the upload works so I have isolated the fact it isn't set.

I have the csrf token added in the form itself as well and in ajax wrapper.

Thanks
Reply
#2

Assuming that the csrf token is included in the data sent to the server a failure to accept the POST is usually because the csrf has not been refreshed after a previous POST. Let me try to make that more clear. You only get to make one POST request using any given csrf token.

Without seeing your code it's impossible to offer concrete advice.
Reply
#3

(This post was last modified: 06-04-2020, 06:09 AM by Goddard.)

(06-03-2020, 07:56 AM)dave friend Wrote: Assuming that the csrf token is included in the data sent to the server a failure to accept the POST is usually because the csrf has not been refreshed after a previous POST. Let me try to make that more clear. You only get to make one POST request using any given csrf token.

Without seeing your code it's impossible to offer concrete advice.


It works fine when I use the jquery serialize.  If I use this


Code:
            var formData = new FormData(this);
            var file_data = $('#document').prop('files')[0];
          formData.append('file', file_data);
          formData.append('<?php echo $this->security->get_csrf_token_name(); ?>', '<?php echo $this->security->get_csrf_hash(); ?>');

         


It doesn't work.


Here is a complete ajax request.


;
Code:
        $('form#documents-form').submit(function(e) {
            e.preventDefault();
            var formData = new FormData(this);
            var file_data = $('#document').prop('files')[0];
          formData.append('file', file_data);
          formData.append('<?php echo $this->security->get_csrf_token_name(); ?>', '<?php echo $this->security->get_csrf_hash(); ?>');
         
         
            $('.should-disable-add-document-modal-button').attr('disabled', true);

            if(!$("#documents-form").parsley().validate()) {
                return;
            }

            <?php if($document->document_id): ?>
                $.ajax({
                    type: 'POST',
                    url: '/documents/update/<?= $document->document_id; ?><?=$entity_type == 'client' ? '/' . $entity_id : ''; ?>',
                    data: formData,
                    cache: false,
                    processData: false,
                    contentType: false,
                    success: function (data) {
                        $('.should-disable-add-document-modal-button').attr('disabled', false);
                        $('#add-document-modal').modal('hide');
                        refreshDocuments();
                    },
                    error: function(jqXHR, textStatus, errorThrown){
                        console.log(errorThrown);
                    }
                });

            <?php endif; ?>
            formmodified=0

        });
Reply
#4

(This post was last modified: 06-04-2020, 12:24 AM by thejmf.)

1-inspect(f12) your html to make sure that you can see the csrf_token usually is next tag afther <form> open tag
example <input type="hidden" name="csrf_token" value="4d924356536aca777f04c56ade9a8ce7"> if the token is not there any POST request will be 403 forbidden-->hint if you use the form helper to open your forms it will be there 
on the server side
2-
PHP Code:
function fileUpload(){
#do your upload methods
//respond back as json
if(your_condition){ // if upload succesful

$response=[
'crsf_token' => $this->security->get_crsf_hash(),
'status'=> 'success'  
];
}else{ 
//if upload unsuccessful
$response=[
'crsf_token' => $this->security->get_crsf_hash(),
'status'=> 'unsuccess'  
];
}
exit (
json encode($response));



success or not success you always must reset crsf token 
your javascript
3-var formData = new FormData(this);
            var file_data = $('#document').prop('files')[0];
          formData.append('file', file_data);
** this is going to work fine. however when your ajax respond back it must bring a new csrf_token to replace the old one.
example;
Code:
$.ajax({

              url:'YOUR URL',
              type:"POST",
              data:formData ,
              cache: false,
              contentType: false,
              processData: false,
              success: function (responseJson) {
                  $('input[name=csrf_token]').val( responseJson.csrf_token);  <----this is the key refresh the token
               }
   

        }); 


like dave mentioned you can only use the a token one time
Reply
#5

Please use code tags when listing source code it makes it easy to read.

Remove the space in each tags:

[ code] your code [ /code]

Or just use the forums advanced editor.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#6

I added the code tags.
Reply
#7

Are you adding a hidden field to #documents-form with the CSRF name/value pair?

You should be. If you do then FormData(this) will pick up all form's fields without you having to explicitly append them to the formData object.

Remember that the CSRF hash will change each time the server receives a POST. So the value of the CSRF field on the form needs to be updated if you plan to make another POST without first making a GET to refresh the whole page.
Reply
#8

(06-04-2020, 02:54 AM)InsiteFX Wrote: Please use code tags when listing source code it makes it easy to read.

Remove the space in each tags:

[ code] your code [ /code]

Or just use the forums advanced editor.

(06-04-2020, 10:36 AM)dave friend Wrote: Are you adding a hidden field to #documents-form with the CSRF name/value pair?

You should be. If you do then FormData(this) will pick up all form's fields without you having to explicitly append them to the formData object.

Remember that the CSRF hash will change each time the server receives a POST.  So the value of the CSRF field on the form needs to be updated if you plan to make another POST without first making a GET to refresh the whole page.



Yes, I am doing that.
Reply
#9

It even shows the csrf token in the post params in my browser developer tools.
Reply
#10

(06-09-2020, 06:29 AM)Goddard Wrote: It even shows the csrf token in the post params in my browser developer tools.
did you read my post?? if you still can get it please get bad to me im willing to help I strugle a lot making this to work
Reply




Theme © iAndrew 2016 - Forum software by © MyBB