Using nginx to enable custom domains in Auth0

In this post, I’m sharing the nginx config needed to set up a reverse proxy for enabling custom domains in Auth0.

I’ll start by explaining why I needed this, but if you don’t care about that, you can just skip straight to the code.

I’ve mentioned before that I use Auth0 for authentication and authorization in Machine Learning for Kids. (And I’ve mentioned before that the developer experience using Auth0 is generally fantastic).

But I’ve had one auth-related complaint from schools since launching the site. And it’s been increasing in the last couple of months:

Users who have their web browsers set to block third-party cookies weren’t able to log in.

This is because the cookies were coming from an auth0.com domain, and not machinelearningforkids.co.uk.

There was an error message on the site for when this happened, advising schools to enable third-party cookies (or at least white-list ‘ml-for-kids.auth0.com’). And I managed to get away with it for a while, as blocking third-party cookies seems to have been a very rare thing to do.

Even then, it wasn’t an ideal solution. Some teachers who ran into this problem were either unable or unwilling to do alter the setting. And even the ones who are willing to do it and are familiar with how to do it on their particular web browsers then need to do it for every computer in their classroom.

What’s making it worse has been that this setting being enabled has been on the increase. I know that Safari enables it by default, but the few analytics on the site I look at suggest that it’s not that – Safari usage is fairly low. My guess is that there is an increase in school administrators making it part of the default settings for students.

So I needed to fix the problem properly.

Auth0 do have documentation for how to fix this. And it’s all great, except for the step where you set up a reverse proxy.

The instructions assume that you’re using AWS and give you step-by-step instructions for setting up AWS CloudFront. As I’ve mentioned before, I’m running my site in IBM Cloud, so I needed to translate their instructions into something a little more generic.

The point of this post is to share how I did it in case it’s useful to anyone else.

The objective was to do something like this:

Set up a reverse proxy on the same domain as the rest of the site, that can forward the requests to the Auth0 endpoint.

The easiest way I found to run this in IBM Cloud was to use an instance of nginx.

You’ll need to replace your-proxy-name with a unique name.
Replace your-custom-domain.com with your own domain – so for me, this was login.machinelearningforkids.co.uk
And you need to use the values you get from setting up a custom domain in Auth0 for the CNAME_API_KEY and PROXY_PASS_HOST.

manifest.yaml

applications:
- name: your-proxy-name
  memory: 32M
  disk_quota: 32M
  path: .
  buildpack: https://github.com/cloudfoundry/nginx-buildpack.git
  routes:
  - route: login.your-custom-domain.com
  env:
    CNAME_API_KEY: you-get-this-from-auth0
    PROXY_PASS_HOST: you-get-this-from-auth0

nginx.conf

# write errors to stderr where Cloud Foundry can grab them
error_log stderr;

# leave as default for now
events { worker_connections 1024; }

http {
  server {
    # get the port number from Cloud Foundry
    listen {{port}};

    location / {
      proxy_pass https://{{env "PROXY_PASS_HOST"}}/;
      proxy_set_header cname-api-key "{{env "CNAME_API_KEY"}}";

      proxy_pass_header Set-Cookie;
      proxy_pass_header User-Agent;
      proxy_pass_header Origin;
      proxy_pass_header Referer;

      # Cloud Foundry's access log is good enough, so save a little
      # disk space by not asking nginx to create another
      access_log off;
    }
  }
}

(You might also want to tweak the memory and disk limit. I’ve actually set up an auto-scaler to scale it up if/when the usage increases, so I’m confortable starting with a small footprint. Plus I’m actually running multiple instances of the proxy, spread across different geographic locations, with DNS failover in front of them, in the same way that I do for the main site. So I don’t have one proxy needing to do all the work. I just didn’t want to complicate this post by including all of the config for that.)

Then it’s just a matter of running ibmcloud app push to deploy it.

Tags: ,

Leave a Reply