I am using devise
to sign up/in.
routes
get 'profile' => 'profile#get_profile' post 'profile' => 'profile#create_profile'
and profile_controller
def get_profile render json: {user: current_user}, status: :ok end def create_profile render json: {user: current_user}, status: :ok end
GET: http://localhost:3000/user/profile returns the expected output. However,
POST request throws an error saying:
ActionController::InvalidAuthenticityToken in User::ProfileController#create_profile
.
Please demystify this behavior.
Resolution. This error can be due to corrupted cookie in your browser. Clear your browsers cache and cookies, restart the browser and try to log in. If the error remains, the problem is that your browser has blocked any cookies from or because OCLCs Zendesk User Portal.
This error means that the app has experienced an authentication problem and can't verify your account information. If it occurs, you'll be automatically signed out of your account. You need to sign in to your account to continue working on your projects.
An authentication token (security token) is a “trusted device” used to access an electronically restricted resource (usually an application or a corporate network). It can be seen as an electronic key that enables a user to authenticate and prove his identity by storing some sort of personal information.
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 formprotect_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 endpointprotect_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:
Rails.application.routes.draw do resources :profiles namespace :api do namespace :v1 do resources :profiles end end end
# 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
(standard controller for html requests)
# app/controllers/profiles_controller.rb class ProfilesController < ApplicationController # POST yoursites.com/profiles def create end end
(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
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"]')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With