I have a Rails app that runs in a Docker container which is assigned an ip 172.17.0.3
. Incoming requests to the host machine 51.x.x.x
are forwarded to the rails app in 172.17.0.3
. More specifically, this was done as such:
docker run -p 8080:8080 rails_app
However, Rails app throws Can't verify CSRF token authenticity
error when a user tries to access some of the pages. My suspicion is that Rails thinks the incoming request is an attack, since the ip of the destination doesn't match the ip of the Rails app - i.e. user requests are directed to the host machine 51.x.x.x
, whereas Rails actual location is at 172.17.0.3
Is there any way for me to tell Rails that these requests are legit? As an additional info, I use devise
for authentication, and unicorn
as the server.
Some of you might be tempted to suggest changing protect_from_forgery with: :exception
to :null_session
, but the application works just fine when not placed behind a proxy. Besides, some of the logic will not work when I changed that part since I think the setting messes with the way a user session is handled.
This is the layout of my network:
(user from public network) ----> (proxy) ----> (rails app on a private network)
(202.x.x.x) (51.x.x.x) (172.x.x.x)
EDIT:
The app is in development
settings. Here's the error I got in log/development.log
files.
Started POST "/register" for 202.x.x.x at 2014-11-18 02:27:11 +0000
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"aBG3nIAKK1ALMJ1DDYFlMkmqISMBMZc3iLmaeD2byG8=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 2ms
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:176:in `handle_unverified_request'
actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:202:in `handle_unverified_request'
devise (3.4.0) lib/devise/controllers/helpers.rb:251:in `handle_unverified_request'
actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:197:in `verify_authenticity_token'
activesupport (4.1.4) lib/active_support/callbacks.rb:424:in `block in make_lambda'
activesupport (4.1.4) lib/active_support/callbacks.rb:160:in `call'
activesupport (4.1.4) lib/active_support/callbacks.rb:160:in `block in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in `call'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in `block in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `call'
activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `block in halting_and_conditional'
activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `call'
activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `block in halting_and_conditional'
activesupport (4.1.4) lib/active_support/callbacks.rb:86:in `run_callbacks'
actionpack (4.1.4) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (4.1.4) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.1.4) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.1.4) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.1.4) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (4.1.4) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
activerecord (4.1.4) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.1.4) lib/abstract_controller/base.rb:136:in `process'
actionview (4.1.4) lib/action_view/rendering.rb:30:in `process'
actionpack (4.1.4) lib/action_controller/metal.rb:196:in `dispatch'
actionpack (4.1.4) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.1.4) lib/action_controller/metal.rb:232:in `block in action'
actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in `call'
actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in `dispatch'
actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:50:in `call'
actionpack (4.1.4) lib/action_dispatch/routing/mapper.rb:45:in `call'
actionpack (4.1.4) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:678:in `call'
omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
warden (1.2.3) lib/warden/manager.rb:34:in `catch'
warden (1.2.3) lib/warden/manager.rb:34:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:35:in `call'
rack (1.5.2) lib/rack/head.rb:11:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/flash.rb:254:in `call'
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:560:in `call'
activerecord (4.1.4) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in `call'
activerecord (4.1.4) lib/active_record/migration.rb:380:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.1.4) lib/active_support/callbacks.rb:82:in `run_callbacks'
actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/reloader.rb:73:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.1.4) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.1.4) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.1.4) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.1.4) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
activesupport (4.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
actionpack (4.1.4) lib/action_dispatch/middleware/static.rb:64:in `call'
rack-cors (0.2.9) lib/rack/cors.rb:54:in `call'
rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
railties (4.1.4) lib/rails/engine.rb:514:in `call'
railties (4.1.4) lib/rails/application.rb:144:in `call'
rack (1.5.2) lib/rack/lint.rb:49:in `_call'
rack (1.5.2) lib/rack/lint.rb:37:in `call'
rack (1.5.2) lib/rack/showexceptions.rb:24:in `call'
rack (1.5.2) lib/rack/commonlogger.rb:33:in `call'
sinatra (1.4.5) lib/sinatra/base.rb:217:in `call'
rack (1.5.2) lib/rack/chunked.rb:43:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
unicorn (4.8.3) lib/unicorn/http_server.rb:576:in `process_client'
unicorn (4.8.3) lib/unicorn/http_server.rb:670:in `worker_loop'
unicorn (4.8.3) lib/unicorn/http_server.rb:525:in `spawn_missing_workers'
unicorn (4.8.3) lib/unicorn/http_server.rb:140:in `start'
unicorn (4.8.3) bin/unicorn:126:in `<top (required)>'
From a cursory reading of the 'protect_from_forgery method', we find the following:
Which has a before action callback called 'verify_authenticity_token'. If we look at its source we find the following:
From there we note that it calls 'verified_request?'.
Given the nature of the raised exception, I would think that one or more of those conditions are not being met. I don't think that it has anything to do with the IP addressing.