Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
672 views
in Technique[技术] by (71.8m points)

jquery - How to pass along CSRF token in an AJAX post request for a form?

I'm using Scala Play! 2.6 Framework, but that may not be the issue. I'm using their Javascript routing - and it seems to work ok, but it's having issues. I have a form, which when rendered produces this, with a CSRF token:

<form method="post" id="myForm" action="someURL">

<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
  <input type="text" id="sometext">
  <button type="submit"> Submit! </button>

</form>

And here's roughly, my AJAX:

$(document).on('submit', '#myForm', function (event) {

 event.preventDefault();
   var data = {
    textvalue: $('#sometext').val()
   }
 var route = jsRoutes.controllers.DashboardController.postNewProject()
 $.ajax({
    url: route.url,
    type: route.type,
    data : JSON.stringify(data),
    contentType : 'application/json',
    success: function (data) { ...      },
    error: function (data) { ...  }
        })

});

But when I post this, I am getting an UNAUTHORIZED response back from my Server, and my console in IntelliJ is telling me the CSRF check is failing. How would I pass along the CSRF token in the request?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, after fighting this for a few hours and trying to decrypt Play's frequently-lacking-context-Documentation on the subject, I've got it.

So, from their docs:

To allow simple protection for non browser requests, Play only checks requests with cookies in the header. If you are making requests with AJAX, you can place the CSRF token in the HTML page, and then add it to the request using the Csrf-Token header.

And then there's no code or example. Thanks Play. Very descriptive. Anyway, here's how:

in your view.html.formTemplate you might write in IntelliJ:

@()
<form method="post" id="myForm" action="someURL">

@helper.CSRF.formField  <!-- This auto-generates a token for you -->
  <input type="text" id="sometext">
  <button type="submit"> Submit! </button>

</form>

And this will render like this when delivered to the client:

<form method="post" id="myForm" action="someURL">

<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
  <input type="text" id="sometext">
  <button type="submit"> Submit! </button>

</form>

Ok, almost there, now we have to create our AJAX call. I have all of mine in a separate main.js file, but you could also put this in your view.html.formTemplate if you want.

$(document).on('submit', '#myForm', function (event) {

 event.preventDefault();
   var data = {
    myTextToPass: $('#sometext').val()
   }
 // LOOK AT ME! BETWEEN HERE AND
 var token =  $('input[name="csrfToken"]').attr('value')
    $.ajaxSetup({
        beforeSend: function(xhr) {
            xhr.setRequestHeader('Csrf-Token', token);
        }
    });
// HERE
 var route = jsRoutes.controllers.DashboardController.postNewProject()
 $.ajax({
    url: route.url,
    type: route.type,
    data : JSON.stringify(data),
    contentType : 'application/json',
    success: function (data) { ...      },
    error: function (data) { ...  }
        })

});

With this line: var token = $('input[name="csrfToken"]').attr('value') You are plucking out the CSRF token auto generated in your form field and grabbing its value in a var to be used in your Javascript.

The other important chunk from all that AJAX is here:

$.ajaxSetup({
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Csrf-Token', token);
            }
        });

Using the $.ajaxSetup, you can set what's in the header. This is what you have to infer from their documentation:

add it to the request using the Csrf-Token header.

Good luck! Let me know if this is clear.


Note: when using lusca, use X-CSRF-Token instead of Csrf-Token.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...