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
709 views
in Technique[技术] by (71.8m points)

Rails: Can't verify CSRF token authenticity when making a POST request

I want to make POST request to my local dev, like this:

  HTTParty.post('http://localhost:3000/fetch_heroku',
                :body => {:type => 'product'},)

However, from the server console it reports

Started POST "/fetch_heroku" for 127.0.0.1 at 2016-02-03 23:33:39 +0800
  ActiveRecord::SchemaMigration Load (0.0ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by AdminController#fetch_heroku as */*
  Parameters: {"type"=>"product"}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms

Here is my controller and routes setup, it's quite simple.

  def fetch_heroku
    if params[:type] == 'product'
      flash[:alert] = 'Fetch Product From Heroku'
      Heroku.get_product
    end
  end

  post 'fetch_heroku' => 'admin#fetch_heroku'

I'm not sure what I need to do? To turn off the CSRF would certainly work, but I think it should be my mistake when creating such an API.

Is there any other setup I need to do?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Cross site request forgery (CSRF/XSRF) is when a malicious web page tricks users into performing a request that is not intended for example by using bookmarklets, iframes or just by creating a page which is visually similar enough to fool users.

The Rails CSRF protection is made for "classical" web apps - it simply gives a degree of assurance that the request originated from your own web app. A CSRF token works like a secret that only your server knows - Rails generates a random token and stores it in the session. Your forms send the token via a hidden input and Rails verifies that any non GET request includes a token that matches what is stored in the session.

However an API is usually by definition cross site and meant to be used in more than your web app, which means that the whole concept of CSRF does not quite apply.

Instead you should use a token based strategy of authenticating API requests with an API key and secret since you are verifying that the request comes from an approved API client - not from your own app.

You can deactivate CSRF as pointed out by @dcestari:

class ApiController < ActionController::Base
  protect_from_forgery with: :null_session
end

Updated. In Rails 5 you can generate API only applications by using the --api option:

rails new appname --api

They do not include the CSRF middleware and many other components that are superflouus.


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

1.4m articles

1.4m replys

5 comments

56.9k users

...