Next Auth as a Microservice

TL;DR: A blog post about the process of building a Next-Auth-based authentication microservice. Here is a GitHub repo using Next.js and Express that puts this blog post into code.

Over the past few weeks, I have been designing the system to power my next large-scale application. My requirements are as follows, three Next.js apps that use a single passwordless authentication service to connect user-auth across all the apps. At first, I thought, well I’ll just use Next Auth and the same database for each app to store session and user data. In practice, this is a terrible way of organizing authentication. There is a ton of duplicate boilerplate code. For every application, you need to keep the database schema (for Prisma or some other Object Relational Mapping tool [ORMs]) in sync and make sure that you are all sharing cookies and local storage cross-domain. A thing that is an incredibly difficult task for a solo developer like me and leads to potential security flaws (like CSRF and other forgery attacks). So my solution is a single authentication service that manages cookie storage and logging independently of the other apps. In addition to a single server, you can then use a monorepo tool like Lerna, NX, or my favorite Turborepo, to share database schemas, UI components, config files, and any other code you might want to share between apps. It does not matter what tech stack or tools you use to implement the auth-server, it just has to be a basic server.

To meet my requirements, I chose Express for my backend authentication server, Next.js for my web apps, Prisma with PostgreSQL for my database, and all of that wrapped up inside a Turborepo. Turborepo is a young startup that provides a lightweight solution to developing in large monolithic codebases, it is powered by NPM and Yarn workspaces, to share code between packages and apps. I recommend you try it out sometime. Anyway, the tech stack I chose may be considered as the hype beast stack, however, it is a lot of fun to work with. I’ve drawn a system diagram to illustrate the macro picture of how my app works.

System Design Diagram

The three web apps all talk to the server which talks to the database. But each individually talks to the database for their app-specific needs. This makes sense because the server is responsible for data that needs to be shared across the apps. I’ve built and deployed a basic example app here. You can find the source code on my GitHub.

To get into the nitty-gritty of how the server works, it just uses Next-Auth.js wrapper on an Express server. It's pretty simple when Next Auth handles all the security and actual authentication. One annoyance of using the Next Auth wrapper is that cross-origin resource sharing (CORS) and security can become possible issues. To allow credential sharing in CORS, you must set the proper header on your requests and allow only specific domains to make requests to your site. Once I solved these specific issues it was very easy to integrate into a Next.js app. Each app just fetches data from the server that returns a JSON object with the user’s data. Here’s a diagram of how authentication works.

Authentication Diagram

It’s a normal and basic auth flow that can scale to support any number of apps. The whole reason for this post is to give an example of how Next Auth can support multi-app platforms without code duplication and possible security flaws.