Next.js and JWT

(November 02, 2018)

In pursuit of SSR (Server side rendering for TTPB, making a React app good for SEO), I found a tool called Next.JS

There was a bit of fiddling with it first, but I grasped it eventually. It has code-splitting (making the React bundle smaller and load just the data it needs for each page), easy peasy SSR and a bunch of other useful features.

I converted the existing project over to Next.js, however I hit a few roadblocks.

The main one was a mis-understanding on my behalf as to how Next.JS fits in. It's essentially like a server specifically for your front-end. The user hits the page, Next.js renders the React app and sends it down in a neat small package and the user can click links and interact as normal.

However I couldn't figure out where the database fits in, the trick: it doesn't. Next.js encourages you to call your API routes via a special lifecycle method called getInitialProps.

Once past this, I had my old Koa API server still connected up. But the next roadblock was how do I fit authentication in, if I can't access a database in Next.JS.

You are discouraged from doing so, but I went against it a little tiny bit. (I'm still not sure if I'm doing this entirely correctly, but it's not slow and it doesn't seem to backwards).

You can serve you Next.JS pages via a Koa server, which is what I ended up doing. I smooshed Passport.js in, setup my previous OAuth routes inside the Next.js server, had it store only new users and a JWT in the database and hey presto.

The process I had before was a bit more contrived:

  • A user hits the page with auth links
  • The user clicks it and is sent to the API server
  • The API server sends them to Facebook or Google
  • Which sends them back to the API server
  • Stores the user or fetches the user
  • Creates a short lived token
  • Sends the token back to Next.js
  • Next.js sends the token in getInitalProps to the API server
  • Next.js receives the JWT and can communicate

Instead of that whole mess, I broke the rule about not including a database:

  • A user hits the page with auth links
  • The user clicks the link and is sent to a route within Next.js
  • Next.js sends them to Facebook or Google
  • Which sends them back to Next.js routes
  • Stores the user or fetches the user
  • Next.js creates and stores the JWT
  • JWT is shared through the shared database and can now be used to send to the API server.

I still think maybe some of these steps could be removed, if I had them both running on the same port perhaps it might be different or a reverse proxy could help share the cookie token, but this works. I'm happy with it.