I have a webapp that is loaded through an iframe using phonegap 2.3.0 for Windows Phone 8 SDK. The problem with loading it through the iframe is that it causes Can't verify CSRF token authencity
on the Rails side when I send a $.post()
request.
I tried a couple of approaches such as overwrite the $.post()
to use $.ajax()
to setHeaderRequest
with the token, and also $.ajaxSetup()
When I disable protect_from_forgery
or verify_authenticity_token
, the app loads correctly.
I believe the problem is caused because the webapp is located in another domain (cross domain issues) and csrf is simply trying to prevent clickjacking. Is there are way to bypass this problem?
Here is an example of how I am posting:
$.post(url, {app: {played: tiles}, no: no}, function (response) {
linkTo('#app_button', response['next']);
});
Example:
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').prop('content'));
}
});
Edit: I have been able to pass authenticity token as a parameter into my post request with the same error. I am starting to beleive the error is not cause by the token. What are other reasons why the error occurs?
Log:
[2539 - 2013/03/06 15:37:42] (INFO) Parameters: {"app"=>{"played"=>"tiles"}, "no"=>"no", "authenticity_token"=>"yBpUImzjtKGIejh/WCekv/GCi1zjPirib22plqfLJ1Y="}
[2539 - 2013/03/06 15:37:42] (WARN) WARNING: Can't verify CSRF token authenticity
[2539 - 2013/03/06 15:37:42] (INFO) User agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)
[2539 - 2013/03/06 15:37:42] (DEBUG) User Load (1.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
[2539 - 2013/03/06 15:37:42] (DEBUG) CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
[2539 - 2013/03/06 15:37:42] (DEBUG) CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
[2539 - 2013/03/06 15:37:42] (WARN) Lost session [118.143.97.82] (/locations/1/games) - Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)
[2539 - 2013/03/06 15:37:42] (DEBUG) CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
You can turn CSRF off for certain controller actions. You can make a new action (let's say iframe) for the purpose of the AJAX call and add in the controller:
The answer is because of no P3P header which was blocking session storage. You need to add a P3P header to fix this.
Add this hidden field to your form. I had fixed the same issue like that of "Can't Verify CSRF Token Authenticity"
The problem is that you need to fetch a new token after an Ajax POST request because once a token is used it gets invalidated. Here is the code to do this:
In rails whenever a POST reply is sent add these parameters to the response:
Now on the JS side, in the success function of every POST method you can call this function:
like this:
This function will reset all authenticity_token params in all POST forms so that the next request has a valid token. You need to make sure this happens in every POST call, otherwise you'll continue facing this problem.
Also, CSRF is not for preventing clickjacking, it's a separate attack altogether, where another website can make a user click a link that executes an action on your website with the user's session.
@user1555300's answer is right just giving the details.
In
application_controller.rb
add this on topbefore_filter :set_p3p
also add this method
Make sure this is on the
application_controller.rb
not a regular controller.