2013-03-06 8 views
2

У меня есть webapp, загружаемый через iframe с помощью phonegap 2.3.0 для Windows Phone 8 SDK. Проблема с загрузкой через iframe заключается в том, что он вызывает Can't verify CSRF token authencity со стороны Rails при отправке запроса $.post().Причины iframe Не удается проверить подлинность аутентификации CSRF n Rails

Я попробовал несколько таких подходов, как перезаписать на $.post() использовать $.ajax() для setHeaderRequest с маркером, а также $.ajaxSetup()

Когда я отключить protect_from_forgery или verify_authenticity_token, приложение загружает правильно.

Я считаю, что проблема вызвана тем, что webapp находится в другом домене (проблемы с перекрестным доменом), а csrf просто пытается предотвратить щелчок. Есть ли способ обойти эту проблему?

Вот пример того, как я отправляю:

$.post(url, {app: {played: tiles}, no: no}, function (response) { 
     linkTo('#app_button', response['next']); 
    }); 

Пример:

$.ajaxSetup({ 
     beforeSend: function(xhr) { 
     xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').prop('content')); 
     } 
    }); 

Edit: Я был в состоянии передать подлинность маркера в качестве параметра в мой пост запроса с такая же ошибка. Я начинаю считать, что ошибка не является причиной токена. Каковы другие причины возникновения ошибки?

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 

ответ

2

Ответ из-за отсутствия P3P заголовка, который блокировал хранения сессии. Вам нужно добавить заголовок P3P, чтобы исправить это.

+0

Существует жемчужина, которая позволяет рельсам отправлять заголовки P3P: https://github.com/carrot/p3p –

1
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" > 

Добавить скрытое поле в форму. Я исправил ту же проблему, что и «Невозможно проверить подлинность аутентификации CSRF»

+0

Его не форма, а ссылка. Есть ли другой способ передать это? – 2013-03-06 05:50:04

+0

может быть эта ссылка поможет вам http://stackoverflow.com/questions/3141041/how-do-i-add-the-authenticity-token –

+0

Хмм ... токен аутентичности передается в параметр, но все равно получается та же ошибка Параметры: {"app" => {"play" => "tiles"}, "no" => "no", "authenticity_token" => "ECVUG1gL8oHzjnlQgR95zxGMlWLvV2x/Ay7UO99LVv0 ="} – 2013-03-06 06:01:50

1

Вы можете отключить CSRF для определенных действий контроллера. Вы можете сделать новое действие (скажем IFrame) с целью вызова AJAX и добавить в контроллере:

skip_before_filter :verify_authenticity_token, :only => [:iframe] 
1

Проблема в том, что вам нужно получить новый токен после запроса AJAX POST, поскольку после использования токена он становится недействительным. Вот код, чтобы сделать это:

В рельсах всякий раз, когда POST ответ посланных добавить эти параметры в ответ:

def someMethod: 
    result[:csrfParam] = request_forgery_protection_token 
    result[:csrfToken] = form_authenticity_token 
    render :json => result 
end 

Теперь на стороне JS, в функции успеха каждого метода POST вы можете вызвать эту функцию:

var setCsrfToken = function(param, token) { 
    if(param == null || token == null) { 
     console.error("New CSRF param/token not present"); 
    } 
    $("input[name='" + param + "']").val(token); 
} 

так:

setCsrfToken(result["csrfParam"], result["csrfToken"]); 

Эта функция сброса все параметры authenticity_token во всех формах POST, чтобы следующий запрос имел действительный токен. Вы должны убедиться, что это происходит в каждом вызове POST, иначе вы продолжите сталкиваться с этой проблемой.

Кроме того, CSRF не предназначен для предотвращения щелчка, это отдельная атака вообще, где другой веб-сайт может заставить пользователя щелкнуть ссылку, которая выполняет действие на вашем веб-сайте с сеансом пользователя.

0

@ пользователь1555300 ответ правильный, просто подробно указывая.

В application_controller.rb добавить это на верхней

before_filter :set_p3p

добавить этот метод

private 
# for IE, Facebook, and iframe sessions 
def set_p3p 
    headers['P3P'] = 'CP="ALL DSP COR CURa ADMa DEVa OUR IND COM NAV"' 
end 

Убедитесь, что это на application_controller.rb не штатный контроллер.

Смежные вопросы