31

I have a rails application which I am planning to upgrade to rails 5. I am using devise(v4.2.0) along with rails(v5.0.0). As suggested in devise README.md file, I tried moving the protect_from_forgery above the before_filter but still when I am trying to login or update my bug I get an error ActionController::InvalidAuthenticityToken

My Application Controller is

class ApplicationController < ActionController::Base
 protect_from_forgery with: :exception, prepend: true
 before_action :configure_permitted_parameters, if: :devise_controller?

  protected

   def configure_permitted_parameters
     devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
     devise_parameter_sanitizer.permit(:account_update, keys: [:name])
   end

end

And my other BugController is

class BugsController < ApplicationController
  protect_from_forgery prepend: true, with: :exception
  before_action :authenticate_user!
  before_action :set_bug, only: [:show, :edit, :update]

    def update
      respond_to do |format|
      if @bug.update(bug_params)
        format.html { redirect_to @bug, notice: 'Bug was successfully updated.' }
        format.json { render :show, status: :ok, location: @bug }
     else
        format.html { render :edit }
        format.json { render json: @bug.errors, status: :unprocessable_entity }
     end
     end
   end

private
def bug_params
  params.require(:bug).permit(:product, :component, :title, :description, :status_id, :created_by_id, :assigned_to_id)
end


end
H D
  • 603
  • 1
  • 8
  • 26

5 Answers5

81

As indicated in Devise documentation notes for Rails 5

For Rails 5, note that protect_from_forgery is no longer prepended to the before_action chain, so if you have set authenticate_user before protect_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 use protect_from_forgery prepend: true.

Alon Burg
  • 2,500
  • 2
  • 27
  • 32
  • 8
    This seems like a way better option than skipping the verification of the authenticity token!! – Stephen Jul 10 '17 at 09:21
  • 4
    This should be the chosen answer – Tallboy Jan 08 '18 at 22:52
  • This solution helped and in my case too. I have AWS CloudFront with SSL and Route53 and I was have similar issue: I was sending post request to rails app (feedback form without login) and via http all works fine without CSRF token, but over SSL pitost wasn't worked. I was need to add custom origin header at cloudfront to fix issue `Origin header didn't match request.base_url`, then I was have issue `Can't verify CSRF token authenticity` and when I added token to request and added header `'X-CSRF-Token': authenticity_token` I was have issue `InvalidAuthenticityToken` and this solution helped me – VoidVolker May 28 '18 at 13:21
  • Thank you! It's straightforward. – Nitesh Dec 30 '19 at 11:51
  • Would this also apply to rails 6 ? – stevec Oct 06 '20 at 05:52
14

Note: While this answer has the desired effect, it does so by reducing overall security. The below answer by Alon is more correct and maintains the security of the site.

class BugsController < ApplicationController
skip_before_filter :verify_authenticity_token
protect_from_forgery prepend: true, with: :exception
before_action :authenticate_user!
before_action :set_bug, only: [:show, :edit, :update]
end

Like This

Ogre Codes
  • 18,693
  • 1
  • 17
  • 24
Boltz0r
  • 970
  • 5
  • 16
  • 1
    I tried putting `skip_before_filter :verify_authenticity_token` in bugs controller but still does not work. – H D Jul 12 '16 at 14:40
  • In `Bugs controller` `protect_from_forgery prepend: true, with: :exception before_action :authenticate_user! before_action :set_bug, only: [:show, :edit, :update]` – H D Jul 12 '16 at 14:47
  • Tried with your provided answer, but I am still getting error `ActionController::InvalidAuthenticityToken in BugsController#update ` – H D Jul 12 '16 at 14:51
  • put that on application controller – Boltz0r Jul 12 '16 at 14:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117114/discussion-between-hsd-and-boltz0r). – H D Jul 12 '16 at 14:54
  • 5
    It is better to use skip_before_action instead of skip_before_filter... – Mauro Nidola Dec 21 '16 at 07:31
  • I did this and it worked, but in light of the below reply I believe this is a poor answer. – Ogre Codes Sep 06 '18 at 18:53
  • Prefer the answer below from @alon-burg – KenneyE Jan 31 '19 at 00:58
5

I recently hit this in a fairly large way and I found that my error was my application's domain name had recently changed but I forgot to update session_store.rb. That may not be everyone's issue but it will report this as a CSRF error. So please check out config/session_store.rb

fuzzygroup
  • 1,109
  • 12
  • 12
1

I have used something like this and it works for me.

class WelcomeController < ActionController::Base
    protect_from_forgery with: :exception
    before_action :authenticate_model!
end
Yashu Mittal
  • 1,478
  • 3
  • 14
  • 32
1

This decision helped me. I took the decision [from here] [1]. just as for me, the unfortunate name of that topic, using the keywords of error I didn’t get there, so I’ll give in this thread, because here is the exact name of the error. in my case, I "added" the following line to the application_controller.rb file:

protect_from_forgery with:: null_session

there is a solution where it says "REPLACE" line protect_from_forgery with:: exception , if it exists, to the one I quoted above

   [1]: Rails 4 Authenticity Token

Nick
  • 138,499
  • 22
  • 57
  • 95