Welcome Guest, Not a member yet? Register   Sign In
CSRF with fetch API
#1

Can someone help me with this?

Code:
fetch(SITE_CONSTANT+'/login/updateUser', {
    method: "post",
    body: "Some string"
})
    .then(response => response.json())
    .then(data => data.result)
    .then(result => console.log(result));

posting stuff with fetch api from javascript to a controller. It works when I turn off csrf, but does not when it's on.

I tried to do like this:
Code:
let csrfs = document.querySelectorAll('input[name=csrf_token]');
let csrf = {name: csrfs[0].name, value: csrfs[0].value};
fetch(SITE_CONSTANT+'/login/updateUser', {
    method: "post",
    body: [csrf, {name: "a name", value: "a value"}]
})
    .then(response => response.json())
    .then(data => data.result)
    .then(result => console.log(result));

Like how I do with Jquery ajax - but still no dice Sad help?
You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#2

See this: https://github.com/codeigniter4/CodeIgni...ssues/2454

Basically, CSRF behavior differs when it detects an AJAX call, but `fetch` calls are indistinguishable from regular HTTP requests. You can work around this by providing the headers with your `fetch` command:

fetch(url, {
method: "get",
headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
}
Reply
#3

(This post was last modified: 07-07-2020, 12:54 PM by Leo.)

(07-07-2020, 10:26 AM)MGatner Wrote: See this: https://github.com/codeigniter4/CodeIgni...ssues/2454

Basically, CSRF behavior differs when it detects an AJAX call, but `fetch` calls are indistinguishable from regular HTTP requests. You can work around this by providing the headers with your `fetch` command:

fetch(url, {
    method: "get",
    headers: {
      "Content-Type": "application/json",
      "X-Requested-With": "XMLHttpRequest"
    }

Thanks MGatner! But I've no problems at all with the "get" method, fetch works as is for get. It is the post I've had a stub on. Currently, my solution is putting everything in FormData() - and that somehow makes it all work.

Code:
    let form = new FormData();

    let csrfs = document.querySelectorAll('input[name=csrf_token]');
    form.append(csrfs[0].name, csrfs[0].value);

    let pkg = JSON.stringify({
        view: "modules/cartproducts",
        products: productIds
    });
    form.append('json', pkg);

    fetch(SITE_CONSTANT+'/front/fetchProducts', {
        method: "post",
        body: form
    })
        .then(response => response.json())
        .then(data => {
            csrfs.forEach(e => e.value = data.csrf_token);
            if(data.products) {
                document.querySelector('.products').innerHTML = data.products;
                document.dispatchEvent(new CustomEvent('productsFetched'));
            }
        });
You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#4

That was just some example code. Regardless of your method you should still try setting the header:

headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
}

That will signify to CodeIgniter that this is an AKAX request and (hopefully) will get your CSRF working on the backend.
Reply
#5

(This post was last modified: 07-08-2020, 08:44 AM by Leo.)

I tried adding it (to the code I posted earlier), but it broke everything. This is what I got in the logs:
#0 C:\laragon\www\stostolov\vendor\codeigniter4\framework\system\Security\Security.php(233): CodeIgniter\Security\Exceptions\SecurityException::forDisallowedAction()
#1 C:\laragon\www\stostolov\vendor\codeigniter4\framework\system\Filters\CSRF.php(85): CodeIgniter\Security\Security->CSRFVerify(Object(CodeIgniter\HTTP\IncomingRequest))
#2 C:\laragon\www\stostolov\vendor\codeigniter4\framework\system\Filters\Filters.php(173): CodeIgniter\Filters\CSRF->before(Object(CodeIgniter\HTTP\IncomingRequest), NULL)
#3 C:\laragon\www\stostolov\vendor\codeigniter4\framework\system\CodeIgniter.php(378): CodeIgniter\Filters\Filters->run('front/fetchProd...', 'before')
#4 C:\laragon\www\stostolov\vendor\codeigniter4\framework\system\CodeIgniter.php(308): CodeIgniter\CodeIgniter->handleRequest(NULL, Object(Config\Cache), false)
#5 C:\laragon\www\stostolov\public\index.php(45): CodeIgniter\CodeIgniter->run()

Also I tried to simply include the csrf value in the body (see below) - but it didn't work either.
fetch(SITE_CONSTANT+'/whatever', {
method: "post",
body: csrf_val
}).then(response => console.log(response))
You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#6

This makes a lot of sense out of CSRF Protection.

PHP RFC: Semi-Automatic CSRF Protection
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply




Theme © iAndrew 2016 - Forum software by © MyBB