Rails application resources not getting rendered over https - ruby-on-rails

I am using ruby 2.4.0p0 and Rails 5.2.3
In the production.rb file I have done the following setting:
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
if Rails.application.config.force_ssl
Rails.application.routes.default_url_options[:protocol] = 'https'
end
But still the resource are getting rendered on http rather then https do I need to do any thing extra, please provide the desired thing to be done to get all assets getting loaded from s3 loads over https.
The website is live here at: https://tukaweb.com/asset/garments
The s3 resources are at http
ex: http://tukaweb.s3.amazonaws.com/uploads/three_d_garment/thumbnail/7/Womens_Dress_35-41_Thumbnail.png?X-Amz-Expires=600&X-Amz-Date=20200918T060705Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIRDA3IQIVTEPMN6Q%2F20200918%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=1792bd4cc2437abd950b7d16d360d09e64423bdef89f41c24a5386d35e982dfa
need them over https.

The required change should be done inside the carrierwave.rb inside the webapp/config/initializers directory modified the settings as:
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'XXXXXXXXXX',
aws_secret_access_key: 'xxxxxxxxxx',
use_iam_profile: false,
region: 'us-west-2', # optional, defaults to 'us-east-1'
# host: 'ec2-xx-xxx-xx-xx.us-west-2.compute.amazonaws.com', # optional, defaults to nil
:endpoint => 'https://s3.amazonaws.com',
}
config.fog_directory = 'tukaweb' # required
config.fog_public = false # optional, defaults to true
# config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
end
The line which is responsible for changing s3 resource to be downloaded from https instead of http
:endpoint => 'https://s3.amazonaws.com' ## earlier it was 'http://s3.amazonaws.com'

Force SSL only works for the incoming requests to the rail's routes. If you have an image link set to http://image-domain.com/image it's going to use the http, and you'll get a mixed content warning. You need to ensure anything external to the app's routes is going to be using SSL or a secure connection as well.
First thing I do when I see a mixed content warning is to do a global search of the codebase for http:// to find everywhere that isn't using https://. I may or may not do a global find + replace depending on what I see, there are cases where it needs to be http:// or it won't work right (if the site doesn't have an https:// version).
Next thing is to work out what is causing the insecure url, here it is S3, so I would be looking at what uses S3, and working out how I can tell it to use SSL or a secure connection.
Note: The other answer does well explaining what your actual issue is, but this may be more useful to others for general troubleshooting of mixed content issues, and would lead to the same result.

Related

Amazon CloudFront doesn't require me to invalidate objects

I have a ruby on rails application where users can upload their avatar or change it. First I stored the images in Amazon s3 but then I realized that content contents were being served slowly and decided to use Amazon cloudfront.
There is no problem for uploading and getting avatar. However, I can see that an updated photo changes immediately but I expect to invalidate it through cloudfront api. And uploading an image takes a lot of time.
At this point I can't decide whether I use cloudfront correctly or not.
This my carrierwave.rb file inside config/initializer:
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'key',
aws_secret_access_key: 'value',
region: 'us-east-1'
}
config.storage :fog
config.asset_host = 'http://images.my-domain.com'
config.fog_directory = 'bucket_name'
config.fog_public = true
config.fog_attributes = { cache_control: "public, max-age=315576000" }
end
I can't see what I'm missing ? How can I be assure that I'm using cloudfront properly ?
Thanks.
Your images aren't being stored in CloudFront, they're being served through CloudFront's CDN.
First request for an image served through CF looks like this:
Browser -> CloudFront -> S3
|
Browser <- CloudFront <-
The second request for an image just looks like this:
Browser -> CloudFront
|
Browser <-
The second request never hit's CF because CF has cached the result for that URL.
NOW, your avatar's updating immediately is simply probably because it's being uploaded to S3 and resulting in a new URL, and thusly, an immediate update. This is how you want it to work.

Can't Get Devise Emails to Use HTTPS

I'm using Rails 3.2.8 and Devise 2.0.4. I'm trying to get Devise emails to send using the 'https' protocol, but none of the solutions I can find are working.
I've already added this to my config/production.rb file:
config.action_mailer.default_url_options = { :host => 'www.mysite.com', :protocol => 'https' }
And this to the top of the same file...
config.force_ssl = true
My NON-Devise emails are working correctly, but these settings appear to have no affect on the Devise emails. As a result, when the http link is clicked in the email, my Apache server is redirecting to 'https' but the trailing slash is being removed and, thus, the url can't be found. I've tried adding a trailing slash on the Apache server, but that doesn't seem to work, either. I'm not sure what else to try.
Try this including the protocol in your host parameter:
config.action_mailer.default_url_options = { :host => 'https://www.example.com' }
This works in Rails 5 and Devise 4, but you would have to test it in Rails 3.2

One SSL page assets

I have a problems with SSL. I need only one page with SSL, but some of assets don't change protocol on https and browser show warning.
Some fonts, svg-icons and one bg-image still with http.
For assets I use Proc in env config.
config.action_controller.asset_host = Proc.new { |source, request = nil, *_|
if request && request.ssl?
"#{request.protocol}#{request.host_with_port}"
else
'http://www.mybrandnew.com'
end
}
Anybody have this problem?
P.S: for partial SSL I already use ssl_requirement

rails carrierwave + fog speed optimisation

I currently using carrierwave with fog to store and upload images using an s3 bucket but the images load much slower than they should. These images load almost instantly when stored as part of the application - but stored with carrierwave and fog it takes a few seconds.
Is this a problem with my s3 setup or carrierwave/fog? My carrierwave config is the following:
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS', # required
:aws_access_key_id => '***', # required
:aws_secret_access_key => '***', # required
}
config.cache_dir = "#{Rails.root}/tmp/uploads" # To let CarrierWave work on heroku
config.fog_directory = 'bucketname' # required NB: having '.' in the bucket name creates an untrusted certificate
config.fog_public = false # optional, defaults to true
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
end
I do have my s3 bucket configured for the US and I'm located in Australia so that might pose a few problems - but my heroku app is also configured to the US and it loads the same images blazingly quick when they're stored as part of the app itself. Maybe aws isn't the best solution?
Anyway any solutions on how I can improve the speed of image load time would be great. It just seems unnecessarily slower than it should be.
It sounds like you want to use CloudFront, Amazon's CDN (content delivery network) service that integrates with S3. Using a CDN will globally replicate the content you're storing in CDN (for a price), which should improve your load times.
After you set up a CloudFront account and link it to S3, add a line like the following to your CarrierWave configuration:
config.asset_host = "http://1234567.cloudfront.net"
With the URL that you get during CloudFront setup.
Unfortunately it looks like you may also need to set config.fog_public = true for Carrierwave to be able to use Amazon's CDN.

Rails 3.1 ssl is used even if I disabled ssl?

I have added force_ssl in my ApplicationController, and deleted later, but now, every request is still prompted to https. I have tried to add config.force_ssl = false to all the configuration files in application.rb and environments/development.rb, etc., but it doesn't work. When I reboot the server, the requests are still converted to https. Any clue?
Updates:
This happens only when I request the root of the application, e.g. http://localhost:3000/, however in my config/routes.rb file I have specified the url for the root clearly: root :to => 'home#index'
You're seeing the effects of HTTP Strict Transport Security's max-age, which is set by Rack::SSL (which config.force_ssl = true sets up) to something high.
In addition to rebooting your app, you also have to clear the browser cache.
For those who it's still unclear, here is what I did to do the trick.
In application_controller.rb :
before_filter :expire_hsts
[...]
private
def expire_hsts
response.headers["Strict-Transport-Security"] = 'max-age=0'
end
In production.rb
config.force_ssl = false
Clear the cache of your web browser and that's it !
yfeldblum is absolutely correct. Disabling it and making chrome forget the header can be a pain.
Here's what I ended up putting in my config/application.rb
config.middleware.insert_before(Rack::Lock, Rack::SSL, hsts: false, exclude: proc { |env|
!env['PATH_INFO'].start_with?('/manage')
})
** note A: hsts: false is the critical bit
** note B: I'm using 1.9, so my hash syntax might be different than yours.
Beyond that, I had to open this url in Chrome chrome://net-internals/#hsts and remove the domains that had this header set.
Thankfully this didn't make it to production, because Rack::SSL sets a very long expires on this header.
if are you using nginx see option:
proxy_set_header X-Forwarded-Proto https;
and disable it!

Resources