Using a Custom OAuth Provider with NetlifyCMS

At work, we’re in the middle of a site realign and rebuild. As part of that effort, we’re moving to NetlifyCMS. Implementing NetlifyCMS was eerily easy for me. But, I did hit one snag when it came to OAuthing with GitHub. In this post I explain the problem and what I did to get things working.

First, the problem. I didn’t do anything fancy with the NetlifyCMS installation. I used the standard approach described in their docs. One requirement we had was to not use Netlify. We wanted to keep things on our AWS infrastructure, because that’s where all our stuff is. We didn’t want another thing to manage.

Before diving in, here are links to examples described in this post. These might be all you need to get going if you’re building a similar thing:

For NetlifyCMS authenticaton I went with GitHub backend. I got lost there. The docs say:

To enable basic GitHub authentication:

  1. Follow the authentication provider setup steps in the Netlify docs.
  2. Add the following lines to your Netlify CMS config.yml file:
NetlifyCMS docs, "Authentication & Backends - GitHub Backend”

I didn’t want to use Netlify. But I also went ahead and followed the docs they referenced in step one. Even with that, I couldn’t quite figure out what needed to happen. Step two above was fine. But, I could tell something was missing.

The Problem

When I tried to log in to the NetlifyCMS on our deployed site, I would hit a 404. So I knew I was missing some piece, but was unclear what that was. I’d spent a while banging my head against it so I asked a question in the NetlifyCMS Gitter room, but didn’t find help there.

The Solution

To use a GitHub backend with NetlifyCMS, you have to have your own server to handle OAuth. This is a requirement of GitHub’s authentication flow. The good news about that, is that it’s a standard OAuth flow. The bad news about that, is that it’s a standard OAuth flow.

Prior Art

vencax/netlify-cms-github-oauth-provider is an example of what’s needed. It’s mostly an example of a standard OAuth flow with a couple—very—helpful NetlifyCMS-specific bits. That got me almost there, but I still couldn’t get everything working. I was still having trouble understanding how all the pieces fit together.

What I needed to do was build my own server to handle the OAuth flow. This is a thing I’ve done and written about before. OAuth is like that for me. I set it up. Deploy it. Forget it. Then have to give myself a refresher to do again. That’s what the server example in this post is.

The Server

I went with Glitch for this example. For me it’s quickest way to get a server spun up. And the easiest way for me to share it with you.

I put steps in the README to explain what you need to do to get this up and running for your own use.

The user-facing part of the server example exists, but it’s not meant for direct use. If you try to use it directly it’ll look like it’s not doing anything. The idea is for you to copy the example—either on Glitch or your own server—and point your NetlifyCMS client at it using the base_url key described below and in the client example.

The code is 99% standard OAuth handshake handling. A GET followed by a POST to GitHub’s OAuth resources to retrieve the OAuth access token. I left comments in the code to point out what’s happening and what’s NetlifyCMS-specific. The biggest chunk of code that NetlifyCMS needs is this;

const postMsgContent = {
  token: body.access_token,
  provider: "github"
};

const script = `
  <script>
    (function() {
      function recieveMessage(e) {
        console.log("recieveMessage %o", e);

        // send message to main window with the app
        window.opener.postMessage(
          'authorization:github:success:${JSON.stringify(postMsgContent)}',
          e.origin
        );
      }

      window.addEventListener("message", recieveMessage, false);
      window.opener.postMessage("authorizing:github", "*");
  })()
</script>`;

A couple bits of formatting aside, I took this from vencax/netlify-cms-github-oauth-provider. This chunk of code is a little tough to follow. The gist of it is that your NetlifyCMS client JavaScript is gonna get your GitHub access token via postMessage. I tried to find the postMessage handling code in the NetlifyCMS code, but haven’t been able to track it down yet. If anyone knows where that is, I’d love to know.

We put this script in a string because we have the server respond with it. You could also put this in HTML and return the access token a different way, but this a way to make short work of it.

The Client

There’s a single customization needed to make this work with the standard GitHub backend NetlifyCMS configuration. The base_url key.

backend:
  name: github
  branch: master
  repo: tylergaw/netlify-cms-github-oauth-provider-client-example # change this to your repo
  base_url: https://netlify-cms-github-oauth-provider-example.glitch.me # change this to your OAuth server

The other items in config.yml are standard NetlifyCMS config items. base_url needs to be a public URL to the server that handles OAuth for your GitHub application. Like the example in this post.

You can see in the client code that this is a no frills NetlifyCMS setup.

That’s All

We’re a similar setup at StreetCred on our soon-to-launch new site and so far, so good. NetlifyCMS is an excellent project. One that I’ve been wanting for years. It checks all the boxes that other CMSs don’t and I look forward to using it more.

If this post and/or the examples helped you, or if you try to use it and get stuck, send me an email at me@tylergaw.com and let me know.

Thanks for reading