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:
NetlifyCMS docs, "Authentication & Backends - GitHub Backend”
- Follow the authentication provider setup steps in the Netlify docs.
- Add the following lines to your Netlify CMS config.yml file:
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.