https redirect for rails app behind proxy?

14,321

You need to add the following line:

proxy_set_header X-Forwarded-Proto https;

as in

location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Proto https;
      proxy_redirect off;

      if (!-f $request_filename) {
        proxy_pass http://upstreamy;
        break;
      }
 }
Share:
14,321
Ace Suares user1266770
Author by

Ace Suares user1266770

Updated on June 06, 2022

Comments

  • Ace Suares user1266770
    Ace Suares user1266770 almost 2 years

    server declaration in my nginx.conf:

        listen       1.2.3.4:443 ssl;
        root /var/www/myapp/current/public;
        ssl on;
        ssl_certificate /etc/nginx-cert/server.crt;
        ssl_certificate_key /etc/nginx-cert/server.key;
        location / {
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header Host $http_host;
              proxy_redirect off;
    
              if (!-f $request_filename) {
                proxy_pass http://upstreamy;
                break;
              }
         }
    

    upstream declaration in nginx.conf:

    upstream upstreamy {
        server unix:/var/www//myapp/shared/sockets/unicorn.sock fail_timeout=0;
    }
    

    this works fine, myapp is reachable as https://somehost

    but the app is generating http url's for redirects, so for instance when authenticating with devise, the / is redirected to http://somehost/user/sign_in instead of https (from the viewpoint of the rails app, it's all http anyway).

    I tried

    proxy_pass https://upstreamy;
    

    but that just tries to encrypt traffic between nginx and the unicorns that run the rails app.

    I also tried, in application_helper.rb:

    # http://stackoverflow.com/questions/1662262/rails-redirect-with-https
    def url_options
      super
      @_url_options.dup.tap do |options|
      options[:protocol] = Rails.env.production? ? "https://" : "http://"
      options.freeze
    end
    

    but it seems to not work.

    How would one solve this?

    Edit: so, the goal is not to make the rails app to require ssl, or to be forced to use ssl; the goal is to make the rails app generate https:// urls when redirecting... (I think all other urls are relative).

  • Yosep Kim
    Yosep Kim about 12 years
    Awesome! Setting up nginx can be very painful. Very painful... :)
  • nembleton
    nembleton over 11 years
    I couldn't get to use proxy_set_header but I just forwarded everything to my proxy for "post" method and rewrite url for the get. Working very well so far.
  • jmervine
    jmervine over 10 years
    In a lot of cases (although perhaps not yours), it's more useful to use proxy_set_header X-Forwarded-Proto $scheme; so that you're passing X-Forwarded-Proto correctly to your upstream application weather you're on http or https. This is particularly useful when you have a load balancer handling https.
  • Patrick
    Patrick about 10 years
    @jmervine If the load balancer is terminating SSL, communicating with nginx over HTTP which communicates with Rails over HTTP, won't $scheme be (incorrectly) HTTP? When you'd still want Rails to generate HTTPS urls in this case.
  • eprothro
    eprothro about 7 years
    This is not transparent and couples app code to a specific deployment configuration.