updated on 2019-07-20
Amazon Linux 2
Rails 5.2.1
ruby 2.4.2
(アプリケーション、ウェブサーバー)
nginx version: nginx/1.12.2
unicorn 5.5.1
(ssl証明書)
python2-certbot-nginx 0.34.2-1.el7
certbot 0.34.2-3.el7
certbot-nginx 0.34.2-3.el7
「混合コンテンツ: '<URL>'のページはHTTPS経由でロードされましたが、安全でない画像 '<URL>'を要求しました。このコンテンツもHTTPS経由で配信する必要があります」
ページのURLがhttpsなのに、保証されてないurl(http)がリクエストされていること
=> https://[domain] に アクセスするとhttpsで暗号化により通信が保護されるが、画像のプロトコルがhttpであるため、他者にすり替えられた危険なコンテンツの恐れがある
と言っている
activeStorageのURL http://[domain]/rails/active_storage/blobs/xxxxxxxxxx/image.jpg を
http => httpsにするだけ...ですがこれがくせもの。
1: fileアップロード先であるs3にてプロパティ -> static website hosting設定にて
「ウェブサイトのホスティングを無効」 から バケットを指定してhttpsプロトコルにリダイレクト
に変更。
2: Railsのconfig/environments/production.rbにて以下を追記
Rails.application.configure do Rails.application.routes.default_url_options[:protocol] = 'https' Rails.application.routes.default_url_options[:host] = "www.example.com" ... end
3: activestorageのアップロード先のs3にて アクセス権限->CORSの設定にhttp以外にもhttpsでの通信許可を追加した
<CORSRule> <AllowedOrigin>https://xxxx</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <AllowedHeader>*</AllowedHeader> </CORSRule>
4: config/initializersにforce_ssl.rbというファイルを新規作成
( https://medium.com/@stacietaylorcima/rails-active-storage-serve-your-images-over-https-14b916c67a51 を参考にした)
(force_ssl.rb) if Rails.application.config.force_ssl Rails.application.routes.default_url_options[:protocol] = 'https' end
結局プロトコルで矯正すると「「リダイレクトが多すぎます」と表示されてしまう」ためアクセスできなくなるだけだった...
ウェブサーバーにてNginx のリバースプロキシ設定が入ってなかった。
Rails側に過失はなかった。
・Nginx - Rails の場合
NginxでリバースプロキシするときにもSSLはNginxで処理させる場合が多く、プロキシされるアプリケーションサーバにはSSLが解かれた状態でリクエストが届く。
そのため X-Forwarded-Proto ヘッダを使って SSL であることを Railsに伝えなければ、force_ssl が機能しない
# log directory
error_log /var/www/rails/myapp/log/nginx.error.log; #自分のアプリケーション名に変更
access_log /var/www/rails/myapp/log/nginx.access.log; #自分のアプリケーション名に変更
# max body size
client_max_body_size 2G;
upstream app_server {
# for UNIX domain socket setups
server unix:/var/www/rails/myapp/tmp/sockets/unicorn.sock fail_timeout=0; #自分のアプリケーション名に変更
}
server {
listen 80;
server_name ~~~.~~~.~~~.~~~;(#アプリのElastic IPに変更してください)
# nginx so increasing this is generally safe...
keepalive_timeout 5;
# path for static files
root /var/www/rails/myapp/public; #自分のアプリケーション名に変更
# page cache loading
try_files $uri/index.html $uri.html $uri @app;
location @app {
# HTTP headers
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
# Rails error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/rails/myapp/public; #自分のアプリケーション名に変更
}
}
結論、画像表示のコードをいじり、絶対パスから相対パスに書き換えて表示させることにしました。
<% @articles.each do |article| %> <% if article.image.attached? %> - <%= image_tag article.image, :alt => "イメージ", width: '30%', height: '30%' %> + <%= image_tag(url_for(article.image), :alt => "イメージ", width: '30%', height: '30%') %> <% end %> <% end %>
出力されてHTMLでいうと、こんな感じになっています
<img alt="イメージ" width="30%" height="30%" src="http://[domain]/rails/active_storage/blobs/xxxxx/sample.jpg">
<img alt="イメージ" width="30%" height="30%" src="/rails/active_storage/blobs/xxxxx/sample.jpg">
絶対パス => 相対パス でプロトコルに左右されないという形にしました。
やむをえずって感じです。