Rails Active Storage: Serve your images over HTTPS

Are you building a Rails app? Are you trying to load resources over HTTPS? Are you using AWS S3 storage? Are you getting Mixed Content errors? If you said yes to more than one of those questions, this article is for you.

I recently added an upload image feature to an app where the user clicks an upload button, selects an image from their local storage, then the image is stored in and served from an AWS S3 bucket.

After uploading new photos I was getting the following error telling me that the image was not secure:

Mixed Content: The page at ‘https://staging.myapphere/resources?q%5Bidentifier_or_title_or_representations_text_cont_all%5D=lala&q%5Bassignments_user_id_eq%5D=' was loaded over HTTPS, but requested an insecure image ‘http://staging.myapp/rails/active_storage/blobs/theimageiuploaded.jpg'. This content should also be served over HTTPS.

I needed to figure out how to serve these images via HTTPS!

Naturally, I began searching things like, “serve your S3 images over HTTPS”. After all, that’s exactly what I was trying to do. This lead me on a wild goose chase through AWS’s documentation. Articles with that exact title walked me through several processes where I was editing S3 bucket policies or implementing a process using AWS CloudFront. I still couldn’t figure it out.

That’s when a mentor of mine suggested that S3 was already serving my image with HTTPS by default and that the problem was that the Active Storage URL helper was just not generating the “s” in the URL.

The solution: add the following line to your staging and production config files: Rails.application.routes.default_url_options[:protocol] = ‘https’