In this segment we will set up a full stack project that we will be using for the rest of this series
A series covering several strategies of web authentication, as well basic concepts and opinions, with some implementation examples.
Introduction
Welcome! Web authentication is a big topic, but this series will focus mainly on a handful of strategies that I typically utilize most. We will start simple and add on to the demo project to improve performance and security throughout the series.
I’ve set up a GitHub repository that you can follow along with if you’d like, I’ll keep a separate branch for each segment in the series.
Contribute to dlford/web-authentication-demo development by creating an account on GitHub.
A Note on Security
Bear in mind that security is the art of making unwanted behavior more difficult in an effort to deter anyone from succeeding in said behavior. There is no single thing you can do to make something secure, instead a combination of techniques will make something reasonably secure while still being reasonably usable, because security and ease of use are somewhat mutually exclusive.
Adding to that challenge, security is a constant cat-and-mouse game; it’s always evolving.
The Stack
We will be using React for the front-end, Express for the back-end, Prisma for Object-Relational Mapping (ORM), and PostgreSQL for the database. We will implement Redis, an in-memory database, later on in the series.
To make this series easier to follow we will not be using TypeScript.
Requirements
To make the most of this series, you will need the following:
- NodeJS installed on your computer
- Docker or Docker Desktop installed on your computer (we will use Docker for PostgreSQL and Redis)
- Working knowledge of Docker, JavaScript, Express, React, and Prisma is not necessarily required, but would be an advantage
Project Setup
We need to bootstrap a full stack app before we can do much else, here is our basic structure.
- Project Directory
api
: Back-end code.env
: Environment variablesprimsa
: Our database schema and migrations will be heresrc
routes
: Express routesconstants.js
: Constant valuesserver.js
: Express server
web
: Front-end codepublic
: Static filessrc
components
hooks
setupProxy.js
: Used byhttp-proxy-middleware
to proxy the back-end port.
API
Let’s create the api
directory and install our dependencies.
NPM Scripts
start
: Run develop modebuild
: Build production codeserve
: Serve production codeclean
: Remove production codeprisma:format
: Format the schema fileprisma:generate
: Generate JavaScript for your scheme (innode_modules
)prisma:migrate:dev
: Match the database to your schema, create migration if neededprisma:migrate:deploy
: Run migrations on the database
Environment
We’ll need some environment variables so we can easily deploy later. The optional values here will have defaults in the code.
We also need to tell Babel what to support, we’ll just use the defaults for now.
Schema
We’ll start with a basic schema for User, Role, Password, and Session.
Constants
Routes
We’ll set up a health check route for now just to make sure the API is working correctly.
It may seem silly to make an index file to export a single module, but I use this structure to keep everything easy to find and parse when you have complicated routes, you’ll see what I mean later in the series.
Now we need to set up our top-level router.
Express Server
The last thing we need to do for the API is tie it all together with Express.
Database
We need an instance of PostgreSQL, if you don’t have one already we can spin one up with Docker.
Next, we need to generate the JavaScript for our schema.
The --prefix
flag on npm
will change the directory the command is run from, in this case the command will run in the api
directory inside the current working directory.
Then we’ll provision the database with our schema, you will be asked to give the migration a name when you run this command, init
is a good choice for this one, later on you’ll name your migrations based on what they are changing.
With that done, you can now run npm --prefix ./api start
, and visit http://localhost:3001/healthcheck
, you should see the JSON response { "success": true }
.
Front-End
Let’s create the web
directory and install our dependencies.
Proxy the API
We want to make the API available at http://localhost:3000/api
when we are in develop mode, to make development easy. The http-proxy-middleware
package will find this file on its own and set up the proxy for us.
Front-End Environment
We don’t need dotenv
on the front-end, instead we just need to preface our variable names with REACT_APP_
.
Custom Hook for API Calls
To keep things tidy, we’ll put all of our API calls in a custom hook. If that gets unwieldy later we can move some of the logic to other files in a lib
folder.
API Status Component
Let’s make a quick component to show the status of the API.
Now a quick adjustment to App.js
and App.css
to display the component.
Other Niceties
Since this is a mono-repo, let’s add a script to the root directory that starts both the front-end and back-end at the same time.
Now you should be able to run npm start
from the root project directory, when you visit http://localhost:3000
you should see something like this.

Lastly, check the GitHub repo for my ESLint and Prettier configurations if you are so inclined, they were omitted here because they are beyond the scope of this article.
Summary
We now have a very simple full-stack application set up with a React front-end that can communicate with our Express API, as well as a database and schema, which we will put to use in the next segment.
In the next segment, we will set up authentication routes on the API, make sure you so you don’t miss it!