Woop Woop looking for Rack gurus out there

Hello my fellow Rails developers. Any Rack specialist out there?

I have forked out my live app to a staging app whith a dedicated staging environment; for which I’m trying to setup a username/password authentication as per the excellent “Heroku Cookbook” from Mike Coutermarsh. My staging.rb file in the Environment folder looks like:

 # Based on production defaults
  require Rails.root.join('config/environments/production')
  Jbts2018::Application.configure do
  config.middleware.use '::Rack::Auth::Basic' do |user, password|
  [user, password] == ['staging', ENV['STAGING_PASS']]
 end

end

As soon as I set the Heroku Environment as follows:

RACK_ENV: staging RAILS_ENV: staging

the app crashes miserably.

From the Heroku logs the interesting bits show:

2017-11-26T06:08:07.265653+00:00 app[api]: Set RACK_ENV config vars by user 
rodolphe@rgeant.name
2017-11-26T06:08:07.265653+00:00 app[api]: Release v63 created by user 
rodolphe@rgeant.name
2017-11-26T06:08:08.527577+00:00 heroku[web.1]: State changed from crashed to 
starting
2017-11-26T06:08:11.994768+00:00 heroku[web.1]: Starting process with command `   bin/rails server -p 9534 -e 
staging`
2017-11-26T06:08:15.842600+00:00 heroku[web.1]: State changed from starting to 
crashed
2017-11-26T06:08:15.826934+00:00 heroku[web.1]: Process exited with status 1
2017-11-26T06:08:15.765330+00:00 app[web.1]: 
/app/vendor/bundle/ruby/2.4.0/gems/actionpack-
5.1.4/lib/action_dispatch/middleware/stack.rb:35:in `build': undefined method `   new' for "::Rack::Auth::Basic":String 
(NoMethodError)
2017-11-26T06:08:15.765347+00:00 app[web.1]: Did you mean?  next

There must be some error in the following snippet :

config.middleware.use '::Rack::Auth::Basic' 

I’m not too sure what’s wrong though.

Any idea will be most welcome.

Many thanks!

@rodolphe85 Your error message says Rack is trying to invoke "::Rack::Auth::Basic".new but it’s failing because you can’t call new on a String.

Why is it trying to call new? Because it’s expecting to be given a class, not a string.

I think you should be able to do:

config.middleware.use ::Rack::Auth::Basic do |user, password|
  # stuff
end

It’s worth mentioning that Rails ships with basic auth out of the box :smiley: ActionController::HttpAuthentication::Basic

Hi Joel,

Thanks for the very quick answer,

I removed the string from the block as suggested but it still fails miserably this time with the secret.key:

2017-11-30T15:25:17.001176+00:00 heroku[web.1]: State changed from crashed to starting
2017-11-30T15:25:20.683719+00:00 heroku[web.1]: Starting process with command `bin/rails server -p 34488 -e 
staging`
2017-11-30T15:25:24.183572+00:00 heroku[web.1]: Process exited with status 1
2017-11-30T15:25:24.194642+00:00 heroku[web.1]: State changed from starting to crashed
2017-11-30T15:25:24.111927+00:00 app[web.1]: /app/vendor/bundle/ruby/2.4.0/gems/devise-
4.3.0/lib/devise/rails/routes.rb:498:in `raise_no_secret_key': Devise.secret_key was not set. Please add the 
following to your Devise initializer: (RuntimeError)
2017-11-30T15:25:24.111943+00:00 app[web.1]: 
2017-11-30T15:25:24.111944+00:00 app[web.1]:   config.secret_key = 
'629ddf6bcfb38031083f09c518307c85f7fdda12a48939c0c7ed51ca0256790d87fa6d54ee

this after I set both RACK_ENV and RAILS_ENV to staging. Nevermind I’m probably better off using RAILS own authentication method (Which I did not know existed).

Thank you again for these forums and the tutorials from Thoughtbot. You guys rock! :smile:

Rodolphe

Hello again Joel.

I actually got it to work. I added the following to secrets.yml:

staging:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Not too sure if this is best practise though?

Run ‘heroku config’ in your production app so you see all the variables heroku requires, and then you can add these in the staging env config

It is a good practice to have your staging environment as a copy of production, that way you ensure you are testing against the real thing, you should consider keep your staging env that way

Hello Orlando,

Thanks for your input. Indeed by adding

staging:

secret_key_base: <%= ENV[“SECRET_KEY_BASE”] %>

I have used the production config so this is as close as possible. Well I think!