Monday, November 20, 2017

different prefix: “/” and “http:/localhost:3000” with devise

Leave a Comment

I'm using devise with rails 5.1.4. When I'm trying to sign in with a wrong password I get this error:

different prefix: "/" and "http:/localhost:3000"

I'm using rbenv with ruby 2.4.1. I had the same problem with ruby 2.3.3.

Here's the full stacktrace:

    /home/badr/.rbenv/versions/2.4.1/lib/ruby/2.4.0/pathname.rb:520:in `relative_path_from' devise (4.3.0) lib/devise/failure_app.rb:58:in `recall' devise (4.3.0) lib/devise/failure_app.rb:39:in `respond' actionpack (5.1.4) lib/abstract_controller/base.rb:186:in `process_action' actionpack (5.1.4) lib/abstract_controller/base.rb:124:in `process' actionpack (5.1.4) lib/action_controller/metal.rb:189:in `dispatch' actionpack (5.1.4) lib/action_controller/metal.rb:242:in `block in action' devise (4.3.0) lib/devise/failure_app.rb:21:in `call' devise (4.3.0) lib/devise/delegator.rb:5:in `call' warden (1.2.7) lib/warden/manager.rb:143:in `call_failure_app' warden (1.2.7) lib/warden/manager.rb:129:in `process_unauthenticated' warden (1.2.7) lib/warden/manager.rb:44:in `call' rack (2.0.3) lib/rack/etag.rb:25:in `call' rack (2.0.3) lib/rack/conditional_get.rb:38:in `call' rack (2.0.3) lib/rack/head.rb:12:in `call' rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context' rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/cookies.rb:613:in `call' activerecord (5.1.4) lib/active_record/migration.rb:556:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call' activesupport (5.1.4) lib/active_support/callbacks.rb:97:in `run_callbacks' actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:24:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call' web-console (3.5.1) lib/web_console/middleware.rb:135:in `call_app' web-console (3.5.1) lib/web_console/middleware.rb:28:in `block in call' web-console (3.5.1) lib/web_console/middleware.rb:18:in `catch' web-console (3.5.1) lib/web_console/middleware.rb:18:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call' railties (5.1.4) lib/rails/rack/logger.rb:36:in `call_app' railties (5.1.4) lib/rails/rack/logger.rb:24:in `block in call' activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `block in tagged' activesupport (5.1.4) lib/active_support/tagged_logging.rb:26:in `tagged' activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `tagged' railties (5.1.4) lib/rails/rack/logger.rb:24:in `call' sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/remote_ip.rb:79:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/request_id.rb:25:in `call' rack (2.0.3) lib/rack/method_override.rb:22:in `call' rack (2.0.3) lib/rack/runtime.rb:22:in `call' activesupport (5.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call' actionpack (5.1.4) lib/action_dispatch/middleware/static.rb:125:in `call' rack (2.0.3) lib/rack/sendfile.rb:111:in `call' railties (5.1.4) lib/rails/engine.rb:522:in `call' puma (3.10.0) lib/puma/configuration.rb:225:in `call' puma (3.10.0) lib/puma/server.rb:605:in `handle_request' puma (3.10.0) lib/puma/server.rb:437:in `process_client' puma (3.10.0) lib/puma/server.rb:301:in `block in run' puma (3.10.0) lib/puma/thread_pool.rb:120:in `block in spawn_thread' 

Any idea where this might come from ?

Update: I created a workspace on cloud9 to see if the project works fine on an other machine and indeed it does! So it's seems like something is wrong with my ruby installation. Before the issue started to happen I had destroyed the project folder on my linux machine and cloned it again from bitbucket.

1 Answers

Answers 1

This is the Devise Workflow of your action.

You filled the form session/new.html.erb. Devise uses the form_for to bind the form to an object and use the RESTful Routes from your routes.rb file.

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> 

This form_for tag will generate the following html form, resource will be replaced with an object based on the User or Admin Model by your SessionsController#new action with the code self.resource = resource_class.new(sign_in_params)

<form accept-charset="UTF-8" action="/users" method="post" class="nifty_form"> 

The html form will trigger a POST request to url /users when you click on the submit button.

The POST request will be received from your Server router which based on the settings you configured on your routes.rb will decide how to respond.

If your routes.rb file is configured as with Devise guidelines, this will be your routes.rb file

devise_for :users 

which generates the following routes

user_session POST   /users/sign_in                    {controller:"devise/sessions", action:"create"} 

so when the request is received from the server it should be handled from the sessions_controller.rb#create action. You can display this controllers on Github or in your GEMS installed in your RVM or RBENV folders. You can also debug them by setting a binding.pry

  # POST /resource/sign_in   def create     self.resource = warden.authenticate!(auth_options)     set_flash_message!(:notice, :signed_in)     sign_in(resource_name, resource)     yield resource if block_given?     respond_with resource, location: after_sign_in_path_for(resource)   end 

When you decide to use the wrong authentication, you are calling this method

def authenticate! resource  = password.present? && mapping.to.find_for_database_authentication(authentication_hash) hashed = false  if validate(resource){ hashed = true; resource.valid_password?(password) }   remember_me(resource)   resource.after_database_authentication   success!(resource) end  mapping.to.new.password = password if !hashed && Devise.paranoid fail(:not_found_in_database) unless resource end 

So when you give invalid password and email, validate(resource){ hashed = true; resource.valid_password?(password) } will return false and execute this code

mapping.to.new.password = password if !hashed && Devise.paranoid fail(:not_found_in_database) unless resource 

which for some reasons will redirect to the wrong url.

I believe this code is meant to show an error in your page, the view session/new.html.erb. So I believe there is not GET request in Devise standard controller, but just re-rendering the view with the error message.

So my question is, did you overwrite the Devise controller to give it this behavior? Could you share with us your routes.rb file and the output of rake routes?

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment