Create Your Own Authentication System
Fri Feb 28 2025
This is a simple authentication system that you can use in your project. It is written in Typescript and uses Prisma as the ORM. The system is designed to be simple and easy to use. It is also easy to extend and modify to fit your needs.
Introduction
Authentication is a critical part of any web application. It is the process of verifying the identity of a user and ensuring that they have the necessary permissions to access the application. There are many ways to implement authentication in a web application, from using third-party services like OAuth to rolling your own system. In this article, we will explore how to create your own authentication system using Typescript and Prisma.
Prerequisites
Before we get started, make sure you have the following installed on your machine:
- Node.js
- Bun (optional)
Setting up the project
First, create a new Next.js project using the following command:
Next, navigate to the project directory and install the necessary dependencies:
Optionally, if you want to use the serverless adapter (such as Vercel Edge) and the Neon database, you can install the following packages:
Setting up the environment variables
Create a new file called env.ts
in the root of the project with the following content:
This file defines the environment variables required for the application. You can customize the variables based on your needs.
Remember to import this file in your next.config.ts
to validate the environment variables.
Note: The
AUTH_SECRET
variable is used to salt the user's password before hashing it. Run the following command to generate a random secret:
Setting up Prisma
Prisma is an ORM that makes it easy to interact with a database in a Typescript project. To set up Prisma, run the following command:
- The
User
model represents a user in the system. It has fields for the user's name, email, image, password, and other information. - The
Account
model represents an OAuth account linked to a user. It has fields for the provider, provider account ID, and other information. - The
Session
model represents a user session in the system. It has fields for the session token, expiration date, and other information.
Next, run the following command to generate the Prisma client:
This will create the necessary tables in the database and generate the Prisma client.
Finally, create a new file called db.ts
in the server
directory with the following content:
This file sets up the Prisma client with the Neon adapter and exports the db
object for use in other parts of the application.
Implementing authentication
- Create a new file called
session.ts
in theserver/auth
directory with the following content:
This file contains a class called Session
that handles the creation, validation, and invalidation of user sessions. It uses the sha256
function from the @oslojs/crypto
package to hash the session token and the encodeBase32LowerCaseNoPadding
and encodeHexLowerCase
functions from the @oslojs/encoding
package to encode the session token.
- The
createSession
method generates a new session token, saves it to the database, and returns the token and expiration date. - The
validateSessionToken
method checks if a session token is valid, returns the user associated with the token, and updates the expiration date if necessary. - The
invalidateSessionToken
method deletes a session token from the database. - The
invalidateAllSessionTokens
method deletes all session tokens associated with a user from the database.
- Create a new file called
password.ts
in theserver/auth
directory with the following content:
- Create a new file called
auth.ts
in theserver/auth
directory with the following content:
This file contains a class called AuthHandler
that handles user authentication using credentials or OAuth providers. It uses the Password
and Session
classes to manage user passwords and sessions, respectively.
- The
auth
method checks if a user is authenticated based on the session token stored in a cookie or theAuthorization
header. - The
handlers
method handles different types of requests, such as signing in with credentials or OAuth providers and signing out. - The
signIn
method signs in a user using credentials or redirects them to an OAuth provider for authentication. - The
signOut
method invalidates the user's session token.
- Create a new file called
index.ts
in theserver/auth
directory with the following content:
In this blog, i use Discord and Google as OAuth providers. You can add more providers by following the same pattern. You can find more information about the arctic
package here
Setting up Auth in the Next.js app
- Create a auth route in the
app/auth/[[...auth]]
directory with the following content:
- Create
use-session
hook to manage the user session in client-side:
- Set up React Query:
- Create the
use-session
hook:
This hook uses React Query to fetch the user session from the server and provides a refresh
method to refresh the session.
- Optionally, you can add
middleware
to protect routes that require authentication:
Conclusion
In this article, we have explored how to create a simple authentication system using Typescript and Prisma. We have implemented user authentication using credentials and OAuth providers like Discord and Google. The system is designed to be easy to use and extend, making it a good starting point for building more complex authentication systems.
Repository: here