Nginx: force SSL on one path, non-SSL on others

Solution 1:

In your nginx configuration, you should have two "server" areas. One for port 80, and one for port 443 (non-SSL and SSL). Simply add a location in your non-SSL website to redirect to your SSL page.

server {
    root /var/www/
    location / {
    }
    location /user {
        rewrite ^ https://$host$request_uri? permanent;
    }
}

it will forward all traffic that ends up at /user to your https:// server.

Then, in your 443 server, you do the opposite.

server {
    listen 443;
    root /var/www/
    location / {
        rewrite ^ http://$host$request_uri? permanent;
    }
    location /user {
    }
}

Solution 2:

Nginx allows to process both HTTP and HTTPS within the same server block. Thus you don't have to duplicate directives for both and can redirect the path you want to secure

server {
  listen 80 default_server;
  listen 443 ssl;
  ... ssl certificate and other configs ...

  location /user {
    if ($scheme = 'http') {
      rewrite ^ https://$http_host$request_uri? permanent;
    }
  }

  ... your basic configuration ...
}

Be sure not to put ssl on line there because it'll break plain HTTP.

Optionally, you can redirect all other requests from HTTPS back to HTTP the same way:

if ($scheme = 'https') {
  rewrite ^ http://$http_host$request_uri? permanent;
}

UPDATE: as Alexey Ten kindly points out in comments section, checking scheme on each request is not a very bright idea. You should follow declarative way of configuring your nginx. In this case, declare two server blocks with redirects by location, move common logic to a separate file and include it in both. So GruffTech's answer is better.

Tags:

Nginx

Ssl