Send HTTP clients to HTTPS
Once a host answers HTTPS, clients that still call it over plain HTTP should be sent to the HTTPS address. redirect answers such a request itself instead of passing it on to your backend. The answer is a redirect status with a Location header. This guide adds the redirect to orders-api. At the end, a client that calls orders-api over plain HTTP is sent to the same address over HTTPS.
Before you start
- HTTPS that answers for the host: a certificate for
api.example.com, from Serve HTTPS with your certificate. redirect only sends clients to HTTPS; it does not make HTTPS work. - How your clients reach the gateway. Behind a load balancer that ends HTTPS and sends the gateway plain HTTP, the gateway sees every request as plain HTTP, even one the client sent over HTTPS, and would send it to HTTPS again and again. There, do the redirect on the load balancer and leave this plugin off.
- The gateway's HTTPS port is 9443 until whoever runs the gateway publishes HTTPS on the standard HTTPS port, so the
Locationin the answers below carries:9443. - This guide starts from
orders-apias Route requests to a backend leaves it, with no other plugin. A plugin from another guide that this page does not name can change the answers below; remove it first or work on a copy of the route. - The requests below call
/orders/3201?page=2. - The host name of your gateway. In the console it is the first part of the Address line on a route's Overview tab,
api.example.comin this page's examples; replace it in every request below. - The Editor or Environment administrator role in this environment.
Steps
1. Choose redirect
Open orders-api under Routes, select its Plugins tab, then Add plugin at the top right of the tab. Open the General category, or type redirect in the search box. Select redirect, then Configure.
2. Choose the HTTPS redirect and add the plugin
Choose Redirect to HTTPS, one choice that also turns on HTTP to HTTPS. Leave Status code, Append query string and Encode URI as they are. With the HTTPS redirect, the status code is fixed and the query string is kept on its own.
Select Add plugin at the bottom of the panel. The plugin is saved like this:
{
"http_to_https": true
}
From now on, every request to orders-api over plain HTTP is answered with a redirect instead of reaching your backend.
Check it
Call the route over HTTPS, and the request passes as before. Then send the same path over plain HTTP. In this request, the gateway host is the host name and port the gateway answers plain HTTP on.
curl -i 'http://<gateway host>/orders/3201?page=2' \
-H 'Host: api.example.com'
- Over plain HTTP
- A request over plain HTTP to
api.example.comis answered301withLocation: https://api.example.com:9443/orders/3201?page=2: the same host, path and query string over HTTPS, on the gateway's own HTTPS port. - Over plain HTTP, as a POST
- A POST over plain HTTP is answered
308instead, with the sameLocation. - Over HTTPS
- A request that arrives over HTTPS passes untouched: over HTTPS to
api.example.comit reaches your backend and is answered200. - Behind a load balancer that ends HTTPS
- A header X-Forwarded-Proto set to https changes nothing: a request that reaches the gateway over plain HTTP is still answered
301. Behind a load balancer that ends HTTPS and sends the gateway plain HTTP, a client that already called over HTTPS is therefore sent to HTTPS again. - If the route also carries key-auth
- On a route that also carries key-auth, key-auth answers first: a request over plain HTTP without a key is answered
401with{"message":"Missing API key in request"}, not redirected, and one with a valid key is answered301.
What to know
- The client is sent to the same host, path and query string over HTTPS, on the gateway's own HTTPS port. A request for
/orders/3201?page=2is sent tohttps://api.example.com:9443/orders/3201?page=2. - A GET is answered 301 and a POST 308, so the client repeats the POST at the new address.
- A header
X-Forwarded-Protoset tohttpsby a load balancer changes nothing. The gateway goes by how the request reached it. - If the route also carries key-auth from Require an API key, key-auth answers first. A request over plain HTTP without a key is answered 401, not redirected, and one with a valid key is redirected only after its key has crossed the network unencrypted. Give clients the
https://address from the start. - Turning Append query string on beside HTTP to HTTPS is refused when you save: the HTTPS address already carries the query string.
- To send clients of a path that moved to the new path instead, choose Redirect to a URI and set the URI to the new path,
/v2/ordersfor example. The reference page shows it under More scenarios.
Related
- Serve HTTPS with your certificate: the HTTPS this redirect points at.
- Rewrite the path your backend sees: changing the path without the client noticing, instead of a redirect.
- redirect in the reference.