

























Session-based authentication, introduced in 1960 at MIT, is still one of the most commonly implemented authentication strategies.
With session-based authentication, every user sign-in creates a session on the server that is associated with the user record in the database. These sessions include details such as a creation timestamp, expiration timestamp, and session status. The session ID is set in a cookie and sent back to the client so that the server can determine the user making any future requests from that client.
In this article, you’ll learn how to build session-based authentication into a Next.js application, from implementing the proper database tables to updating the website with authentication forms.
There are a set of common requirements when it comes to implementing session-based authentication in any application.
At least two tables are required:
Any tables with records associated with specific users will also need a userId or similar column added to make the association.
Beyond the required functionality to interact with the new database tables, the backend also needs to be able to hash and salt the user passwords so they are not stored in plain text. It’s also best practice to implement sign-up and login form validation server-side so that bad data is not committed to the database.
Protections also need to be added so that the session ID is checked with the database on each request, and that the user's permissions are verified before performing the requested operation or returning data to the client.
Since the frontend is what the user interacts with, there are some expected elements required such as sign-in forms, sign-up forms, and a sign-out button. To provide the best user experience, it’s also recommended to implement validation on the forms so that users get immediate feedback if their input is not acceptable before they submit. It also has the added benefit of preventing bad data from being sent to the server.
You should also ensure that unauthenticated users cannot access routes that are reserved for users who are signed in.
Cookies are a way to store small bits of arbitrary data in your browser. While they can be set in the browser, they are more commonly sent to the client from a server for an HTTP request. Cookies set by a server are automatically sent back to that server with every request.
In the context of session-based authentication, the server will create a cookie to store the session identifier and send it back to the client upon successful sign-in. When a request is made, the server checks the session ID associated with the request and looks up which user the session belongs to so it can properly identify who is making the request and apply the appropriate authorization rules.
While you’ll learn how to build a typical authentication system in this article, user management is a much bigger topic than simply allowing users to create accounts and sign in to your application.
Clerk is a user management platform that's designed to get you up and running with authentication quickly by providing drop-in UI components. For example, the following snippet demonstrates the code required to build a sign-in page into a Next.js application using Clerk:
When using Clerk, you can easily configure the traditional email & password strategy as well as others like social sign-in providers, passkeys, and even email & SMS code authentication.
You’ll also provide your users an elegant way to manage their own account data, reset passwords, and connect multiple authentication providers, giving them the flexibility to sign-in to your application the way they want.
Quillmate is an AI-powered application for writers. Users can use Quillmate to help them develop ideas, draft pieces, and ask the AI assistant to help with various tasks.
Quillmate is built with the following tech:
If you want to follow along, clone the build-nextjs-login-page-start branch from the GitHub repository. Follow the instructions provided in the project’s README before proceeding.
There are two new dependencies that need to be installed before modifying the existing codebase:
bcryptjs - bcryptjs is a very popular hashing library that will be used to hash and salt the passwords before saving them to the database.zod - zod will be used for both client and server-side form validation, ensuring our data is always clean and providing a better user experience.Install those dependencies with the following command:
Now let’s get the database schema updated. Navigate your code editor to prisma/schema.prisma and make the following changes to define the new database tables:
Run the following command in the terminal to update the Prisma client and push the changes to the Neon database:
As mentioned earlier in this guide, you’ll need to separate your public routes from those that require the user to be signed in. In an application with dedicated backends and frontends, you’d typically separate the views in the frontend to prevent unauthorized users from accessing those views, and protect the backend API routes so that tech savvy users can’t bypass protections in the frontend.
Since Next.js is a full-stack framework, you can actually do both using middleware, which provides a way for you to intercept requests and apply your own logic to the request before the user reaches their destination.
Create src/middleware.ts and paste in the following code:
With the database changes and middleware in place, you can now add the necessary forms and logic to allow users to create an account and sign into the application. Each of these routes contain three files as follows:
page.tsx - The client-side sign-up or login page the user will interact with.actions.ts - Server actions that are used to interact with the database to create new users and create sessions.validation.ts - Validation models that are shared between the sign-up or login page and server action, enabling validation on both ends of the application.There are also a few functions that will be shared between both the sign-up and sign-in routes, so let’s get that set up before building them.
Create a the src/app/auth/actions.ts file and populate it with the following:
Since validation.ts is the simplest of the three files, start by creating src/app/signup/validation.ts and paste in the following:
Next, create the server actions file at src/app/signup/actions.ts and paste in the following:
Finally, create src/app/signup/page.tsx and paste in the following:
Now let’s create the sign-in logic and views starting with the validation file as we did in the previous section. Create src/app/signin/validation.ts and paste in the following code:
Next, create the server actions at src/app/signin/actions.ts and populate the file with the following:
Then create the login page at src/app/signin/page.tsx and paste in the following:
At this point, the user can now create an account and sign in as needed, but the /articles route which contains the protected pages still needs to have several pieces updated to ensure users can only work with articles associated with their account and not ALL articles.
Update prisma/schema.prisma one more time to update the Article model so those records are associated with a user by creating the userId column and Prisma relation:
Apply your changes with the same terminal commands as before:
Next, you’ll update the server actions used for the /articles route to store the user’s ID whenever an article record is created, and filter returned articles when the user requests them, ensuring that users can only access the articles they are supposed to.
Update src/app/articles/actions.ts as follows:
Finally, you’ll update src/app/articles/page.tsx to add a sign-out button that leverages the signOut function in our shared authentication utility file:
The last thing to do is update the “Get started” button on the home page to go to /signin instead of /articles, which will let users sign into the application if they are not already:
Now that all the changes are implemented, execute the following command in your terminal to start up the dev server:
Open your browser and navigate to the URL displayed in the terminal and you’ll be able to create a user account, sign into the application, and start creating articles!

After creating an article and chatting with the AI assistant, you can head to the Neon console to explore how the data is structured in the database.

You are now well-equipped to implement session-based authentication within your own application. By following the general guidance introduced at the beginning of this post, you can provide your users the ability to create accounts and sign in to your Next.js site.
While this guide outlines the steps required to implement authentication, adding sign up and sign in to a web application is only one aspect of user management. Consider giving Clerk a try for a complete user management platform that can be configured in minutes, saving you and your team hours of development, testing, and debugging effort.
Feel free to use the provided repository as a resource when building Next.js web applications going forward!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。