问题
All I a sudden I can no longer login to my app production environment on heroku. Or, if I do get in, as soon as I click a new link I get redirected to the login screen where I start seeing errors if I try and login again.
The logs are as follows (this was in the case of login, redirect back to login and then login again).
My applications layout includes CSRF_meta_tags
!!!
%html
%head
%title= full_title(yield(:title))
= include_gon(:init => true)
= stylesheet_link_tag "application", media: "all"
= javascript_include_tag "application"
= csrf_meta_tags
= render 'layouts/shim'
%meta{content: "width=device-width, initial-scale=1.0", name: "viewport"}/
%body.container-fluid
#wrapper
= render 'layouts/navigation'
= render partial: "shared/flash_messages", flash: flash
#content
= yield
= render 'layouts/footer'
%br
- if request.env['HTTP_USER_AGENT'].downcase.match(/android|iphone|ipad/)
- else
= debug(params) if Rails.env.development?
= debug(@current_user) if Rails.env.development?
and my application controller is protect_from_forgery with exception.
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
before_action :authenticate_user!
end
and I have devise for user in my routes file.
devise_for :users, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users/:id' => 'devise/registrations#update', :as => 'user_registration'
end
log files are here for reference.
Started GET "/users/sign_in" for 58.7.233.232 at 2014-05-16 23:52:48 +0000
Processing by Devise::SessionsController#new as HTML
2014-05-16T23:52:48.995008+00:00 heroku[router]: at=info method=GET path=/assets/application-7d1b02fae40091844b4f616c7ec89e83.js host=slapp.herokuapp.com request_id=8f86c336-0bf2-4419-a07d-0c7ecf79cfb4 fwd="58.7.233.232" dyno=web.2 connect=1ms service=2ms status=304 bytes=249
Rendered layouts/_shim.html.haml (0.3ms)
Rendered devise/sessions/new.html.haml within layouts/application (7.9ms)
Rendered layouts/_navigation.html.haml (1.2ms)
Rendered shared/_flash_messages.html.haml (0.4ms)
Rendered layouts/_footer.html.haml (0.4ms)
Completed 200 OK in 18ms (Views: 14.1ms | ActiveRecord: 0.0ms)
2014-05-16T23:52:54.997215+00:00 heroku[router]: at=info method=POST path=/users/sign_in host=slapp.herokuapp.com request_id=6fd107af-4a46-4315-843c-6bbf46827df0 fwd="58.7.233.232" dyno=web.1 connect=7ms service=41ms status=422 bytes=1729
Started POST "/users/sign_in" for 58.7.233.232 at 2014-05-16 23:52:54 +0000
vendor/bundle/ruby/2.0.0/gems/devise-3.2.4/lib/devise/controllers/helpers.rb:182:in `handle_unverified_request'
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"o5NFnMmQQGcmNxPhzvFYOF+ThrcO1cY1VdZozvQmtOI=", "user"=>{"email"=>"admin@domain.com", "password"=>"[FILTERED]"}, "commit"=>"Login"}
Completed 422 Unprocessable Entity in 9ms
vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:160:in `block in halting'
vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_controller/metal/request_forgery_protection.rb:197:in `verify_authenticity_token'
vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:166:in `call'
Can't verify CSRF token authenticity
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_controller/metal/request_forgery_protection.rb:176:in `handle_unverified_request'
vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_controller/metal/request_forgery_protection.rb:202:in `handle_unverified_request'
I am currently troubleshooting with suggestions on this similar question but no luck so far. Considering trying the "protect_from_forgery except: :sign_in" but it seems like an unnecessary compromise if I can find out the root cause.
回答1:
I think the csrf token is being generated in one dyno and the next http request is hitting the second dyno, so the csrf token doesn't match. The csrf token needs saving to a database so it can be shared by both dynos. Try writing out $DYNO when the page is served and when the form is processed. This will show you which dyno is processing the csrf token and whether it is the same dyno or a different one.
来源:https://stackoverflow.com/questions/23706336/get-request-no-json-cant-verify-csrf-token-authenticity-with-devise-3-2-4-on