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?
This question is related to
ruby-on-rails
Since Rails 5 you can also create a new class with ::API instead of ::Base:
class ApiController < ActionController::API
end
Another way to turn off CSRF that won't render a null session is to add:
skip_before_action :verify_authenticity_token
in your Rails Controller. This will ensure you still have access to session info.
Again, make sure you only do this in API controllers or in other places where CSRF protection doesn't quite apply.
If you only want to skip CSRF protection for one or more controller actions (instead of the entire controller), try this
skip_before_action :verify_authenticity_token, only [:webhook, :index, :create]
Where [:webhook, :index, :create]
will skip the check for those 3 actions, but you can change to whichever you want to skip
The simplest solution for the problem is do standard things in your controller or you can directely put it into ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
end
If you want to exclude the sample controller's sample action
class TestController < ApplicationController
protect_from_forgery :except => [:sample]
def sample
render json: @hogehoge
end
end
You can to process requests from outside without any problems.
If you're using Devise, please note that
For Rails 5,
protect_from_forgery
is no longer prepended to thebefore_action
chain, so if you have setauthenticate_user
beforeprotect_from_forgery
, your request will result in "Can't verify CSRF token authenticity." To resolve this, either change the order in which you call them, or useprotect_from_forgery prepend: true
.
There is relevant info on a configuration of CSRF with respect to API controllers on api.rubyonrails.org:
?
It's important to remember that XML or JSON requests are also affected and if you're building an API you should change forgery protection method in
ApplicationController
(by default::exception
):class ApplicationController < ActionController::Base protect_from_forgery unless: -> { request.format.json? } end
We may want to disable CSRF protection for APIs since they are typically designed to be state-less. That is, the request API client will handle the session for you instead of Rails.
?
Source: Stackoverflow.com