Rails 4.1.8:身份验证令牌无法验证

时间:2015-01-23 15:56:29

标签: ruby-on-rails ajax

我是Rails的新手。我有

  <%= csrf_meta_tags %>
  <%= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? %>

在我的application.html.erb中。我需要通过ajax发布表单,我有,

data: data + "&authenticity_token="+AUTH_TOKEN,

data的ajax方法中。我验证了两个令牌,即post方法标头身份验证令牌X-CSRF-Token和我发送的Auth_TOKEN都是相同的。我仍然遇到Can't verify CSRF token authenticity错误。我不想跳过安检,我需要一个正确的方法来处理这个问题。任何的想法?提前谢谢。

表格

 <h3 id="emailModalLabel">Tell Your Friends About Us</h3>
 <form class="form-horizontal col-sm-12 validate" name="emailForm" id="emailForm">
    <div class="form-group"><label>Your Name *</label><label class="error" for="your_name" generated="true"></label><input id="your_name" name="your_name" class="form-control required" placeholder="Your name" data-placement="top" data-trigger="manual" data-content="Must be at least 3 characters long, and must only contain letters." type="text"></div>
    <div class="form-group"><label>Your E-Mail *</label><input id="your_email" name="your_email" class="form-control required email" placeholder="email@you.com (so that your friend can reply to you)" data-placement="top" data-trigger="manual" data-content="Must be a valid e-mail address (user@gmail.com)" type="email"></div>
    <div class="form-group"><label>Friend's Name *</label><input id="friend_name" name="friend_name" class="form-control required" placeholder="Your friend's name" data-placement="top" data-trigger="manual" data-content="Must be at least 3 characters long, and must only contain letters." type="text"></div>
    <div class="form-group"><label>Friend's E-Mail *</label><input id="friend_email" name="friend_email" class="form-control required email" placeholder="email@friend.com (so that you can email them)" data-placement="top" data-trigger="manual" data-content="Must be a valid e-mail address (user@gmail.com)" type="email"></div>
    <div class="form-group"><label>Message</label><textarea id="message" name="message" class="form-control" rows="5" placeholder="Your message here.." data-placement="top" data-trigger="manual"></textarea></div>
    <div class="form-group"><p class="help-block pull-left text-danger hide" id="form-error">&nbsp; The form is not valid. </p></div>
    <span class="pull-right"><button class="btn col-md-5 col-sm-5 col-xs-5" data-dismiss="modal" aria-hidden="true">Cancel</button><button id="emailSubmit" type="submit" class="btn btn-default pull-right col-md-5 col-sm-5 col-xs-5">Send It!</button></span>
</form>

Ajax POST

$("#emailForm").validate({
    rules:{
        your_name: {required: true},
        your_email: {required: true, email: true},
        friend_email: {required: true, email: true},
        friend_name: {required: true}
    },
    submitHandler: function(form) {
        $("#emailSubmit").prop("disabled", true);
        var data = $("form#emailForm").serialize();
        $.ajax({
            type: "POST",
            url: "/send",//process to mail
            data: data + "&authenticity_token="+AUTH_TOKEN,
            success: function(msg){
                if(msg['success']){
                    $(".successContainer").toggleClass( "hide", 1000, "easeOutSine" );
                    setTimeout("$('#emailModal').modal('hide')", 5000);
                }else{
                    $(".errorContainer").toggleClass( "hide", 1000, "easeOutSine" );
                }


            },
            error: function(){
                $(".errorContainer").toggleClass( "hide", 1000, "easeOutSine" );
            }
        });
    }

});

ajax请求中的dataserialized所以它是一个字符串,我将令牌附加到该字符串。

1 个答案:

答案 0 :(得分:0)

这里最好的解决方案是实现一个form_tag内置rails帮助器,如:

<%= form_tag '#', class: 'form-horizontal col-sm-12 validate', name: 'emailForm', id: 'emailForm' do %>
  <div class="form-group">
    <label>Your Name *</label>
    <label class="error" for="your_name" generated="true"></label>
    <%= text_field_tag "your_name", "", id: 'your_name', class: 'form-control required', placeholder: 'Your name', data: { placement: 'top', trigger: 'manual', content: 'Must be at least 3 characters long, and must only contain letters.' }%>
  </div>
  .
  .
  .
<% end %>

注意我刚刚包含了第一个text_fiel_tag,您可以使用Rails包含任何其他字段标记。

这背后的原因是什么?好吧Rails使用令牌来防止CSRF攻击。

对于ajax调用,你必须从表单序列化数据,然后像你现在一样发送它。

使用Rails时的一个好建议,尝试始终使用内置帮助程序,例如表单,图像,链接等。