Invalid Authenticity Token on Post
Get requests don't have an authenticity token.
You will have to add the request forgery stuff to your forms using this
<%= csrf_meta_tag %>
And address via javascript
$('meta[name="csrf-token"]')
To disable CSRF protection
you can edit your ApplicationController
like this:
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
# ...
end
or disable the CSRF protection
for specific controller:
class ProfilesController < ApplicationController
skip_before_action :verify_authenticity_token
# ...
end
:null_session
strategy empties the session instead of raising an exception which is perfect for an API. Because the session is empty, you can't use current_user
method or othes helpers that refer to the session
.
IMPORTANT:
protect_from_forgery with: :null_session
must be used only in specific cases, for example to allow API request (POST/PUT/PATCH/DELETE) without html form- With
protect_from_forgery with: :null_session
you must restrict access to your data with an authorization system because every one could do request against your API endpoint - Don't remove
protect_from_forgery with: :exception
for requests that are done through html form, is dangerous! (read here http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf)
To handle both standard requests (through html form) and API requests generally you have to set up two different controller for the same resource. Example:
Routes
Rails.application.routes.draw do
resources :profiles
namespace :api do
namespace :v1 do
resources :profiles
end
end
end
ApplicationController
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
ProfilesController
(standard controller for html requests)
# app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
# POST yoursites.com/profiles
def create
end
end
Api::V1::ProfilesController
(controller for API requests)
# app/controllers/api/v1/profiles_controller.rb
module Api
module V1
class ProfilesController < ApplicationController
# To allow only json request
protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? }
# POST yoursites.com/api/v1/profiles
def create
end
end
end
end
refereces: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html#method-i-protect_from_forgery