web-dev-qa-db-ja.com

POST 422(Unprocessable Entity)in Rails?ルートまたはコントローラーのため?

私は自分のウェブサイトのユーザーにブランド名についてツイートするための「ポイント」または「クレジット」を提供しようとしています。

適切なビューに派手なTwitterウィジェットがあります...

<p><a  href="https://Twitter.com/share" class="Twitter-share-button" data-text="Check Out This Awesome Website Yay" data-via="BrandName" data-hashtags="ProductName">Tweet</a>
<div id="credited"></div>
<script>window.twttr = (function (d, s, id) {
  var t, js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src= "https://platform.Twitter.com/widgets.js";
  fjs.parentNode.insertBefore(js, fjs);
  return window.twttr || (t = { _e: [], ready: function (f) { t._e.Push(f) } });
}(document, "script", "Twitter-wjs"));
</script>    

JSはすべて書かれていてきれいです。

function creditTweet() {
  $.post(
    "/credit_Tweet",
    {},
    function(result) {
      var text;
      if (result.status === "noop") {
        text = "Thanks for sharing already!";
      } else if (result.status === "ok") {
        text = "5 Kredit Added";
      }
      $("#credited").html(text);
    }
  );
}

$(function() {
  twttr.ready(function (twttr) {
    window.twttr.events.bind('Tweet', creditTweet);
  }); 
});

今、問題はコントローラーにありますORルート(私が投稿している))。POSTはほとんど機能しているので、ルートは問題ないと思います、これはウィキペディアのエラーの説明であるため、「422 Unprocessable Entity(WebDAV; RFC 4918)リクエストは整形式でしたが、セマンティックエラーのために追跡できませんでした。」

それで、コントローラの私のRubyコードに何か問題がありますか?

class SocialKreditController < ApplicationController
    Tweet_CREDIT_AMOUNT = 5

  def credit_Tweet
    if !signed_in?
      render json: { status: :error }
    elsif   current_user.Tweet_credited
        Rails.logger.info "Not crediting #{ current_user.id }"
        render json: { status: :noop }
      else
        Rails.logger.info "Crediting #{ current_user.id }"
        current_user.update_attributes Tweet_credited: true
        current_user.add_points Tweet_CREDIT_AMOUNT
        render json: { status: :ok }
      end
  end
end

そして、私のroutes.rbでは、それはかなり簡単ですので、ここに何か問題があるのではないかと思います...

  get 'social_kredit/credit_Tweet'
  post '/credit_Tweet' => 'social_kredit#credit_Tweet'

このエラーはどこにありますか?私は明らかにHTTPリクエストに関するスマックを知りません。

24
piratetone

うまくいきました!

追加しました...

skip_before_action :verify_authenticity_token

コントローラーに。

この問題は、ログをチェックアウトし、CSRFトークンを検証できなかったときに発見されました。

52
piratetone

ihaztehcodez(2016年に最後にアクティブだったので、答えを投稿するのを助けないだろう)は、skip_before_action :verify_authenticity_tokenテクニックはそれほど安全ではないので、偽造保護を失います。

彼らはベスト/セキュア/「より良い練習」を言及しています、ソリューションはここで言及されています 警告:CSRFトークンの真正性を検証できませんRails

例えば.

$.ajaxSetup({
  headers: {
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
  }
});

または

$.ajax({ url: 'YOUR URL HERE',
  type: 'POST',
  beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
  data: 'someData=' + someData,
  success: function(response) {
    $('#someDiv').html(response);
  }
});

または

これをajaxリクエスト内に配置する

headers: {
  'X-Transaction': 'POST Example',
  'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
0
barlop

私が直面した同じ問題。追加後に整理します

skip_before_action:verify_authenticity_token

jSがデータを呼び出したり送信したりするコントローラーの上部。

class UserController < ApplicationController
    skip_before_action :verify_authenticity_token
    def create
    end
end

コードスニペットに示すように。

0
Shekhar Patil

RailsメタデータをHTMLヘッダーに<%= csrf_meta_tags %>で含める場合]は、以下を生成します。

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="ihwlaOLL232ipKmWYaqbSZacpJegQqooJ+Cj9fLF2e02NTQw7P/MfQyRuzruCax2xYWtEHWsb/uqiiZP6NWH+Q==" />

メタデータからCRSFトークンを取得し、非同期リクエストに渡すことができます。ネイティブjs fetchメソッドを使用すると、x-csrf-tokenヘッダーとして渡すことができます。

これは、標準のReactフォームを拡張するRailsコンポーネントのトリムされたonSaveハンドラです。

  onSaveHandler = (event) => {
    const data = "Foo Bar";
    const metaCsrf = document.querySelector("meta[name='csrf-token']");
    const csrfToken = metaCsrf.getAttribute('content');
    fetch(`/posts/${this.props.post_id}`, {
      method: "PUT",
      body: JSON.stringify({
        content: data
      }),
      headers: {
        'x-csrf-token': csrfToken,
        'content-type': 'application/json',
        'accept': 'application/json'
      },
    }).then(res => {
      console.log("Request complete! response:", res);
    });
  }

偽造防止は良い考えです。このようにして、安全な状態を保ち、Rails構成を台無しにしないでください。

gem 'Rails', '~> 5.0.5'"react": "^16.8.6",の使用

0
Lex