惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
A
About on SuperTechFans
Stack Overflow Blog
Stack Overflow Blog
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
爱范儿
爱范儿
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
V
Visual Studio Blog
有赞技术团队
有赞技术团队
U
Unit 42
D
Docker
小众软件
小众软件
F
Full Disclosure
I
Intezer
Scott Helme
Scott Helme
P
Privacy International News Feed
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
B
Blog
Martin Fowler
Martin Fowler
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Spread Privacy
Spread Privacy
宝玉的分享
宝玉的分享
S
Security Affairs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
月光博客
月光博客
C
Cisco Blogs
云风的 BLOG
云风的 BLOG
Schneier on Security
Schneier on Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Threat Research - Cisco Blogs
量子位
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Heimdal Security Blog
N
Netflix TechBlog - Medium
H
Hacker News: Front Page
P
Proofpoint News Feed
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
S
Schneier on Security

Clerk Blog

Going to production with Clerk Deploy Clerk Init: The fastest way to start a new project Introducing Clerk CLI Middleware-based route protection bypass Postmortem: Clerk System Outage (March 10, 2026) Clerk for the AI era Add API Key support to your SaaS in minutes Postmortem: Clerk System Outage (February 19, 2026) Using Clerk in a React Native app Postmortem: DNS Provider Outage (February 10, 2026) How do I implement passkeys in Next.js? Clerk ranked #4 fastest-growing software vendor on Ramp’s December 2025 list How do I handle JWT verification in Next.js? Committing to Agent Identity: Clerk raises $50m Series C from Menlo and Anthropic’s Anthology Fund What is the best way to handle authentication in Next.js App Router? Postmortem: Database Incident (September 14–18, 2025) How do I add authentication to a Next.js app? Introducing Free Trials in Clerk Billing Postmortem: August 28, 2025 - elevated API latency and errors Introducing Mosaic: Bring Your Brand to Every Authentication Flow Multi-tenant authentication: What you need to know (and how Clerk helps) What are the risks and challenges of multi-tenancy? Resilience in Practice: Regional Failover at Clerk Build a Cross-Platform B2B App with Clerk, Expo, and Supabase Highlights from the MiduDev/Clerk Hackathon Add multi-tenancy to an app built with Clerk, Lovable, and Supabase How to build an AI coding rules app with Clerk, Lovable, and Supabase How to Build Multi-Tenant Authentication with Clerk Choosing the right SaaS architecture: Multi-Tenant vs. Single-Tenant Postmortem: June 26, 2025 service outage How to Design a Multi-Tenant SaaS Architecture What is multi-tenancy and why it matters for B2B SaaS How OAuth Works Synchronize user data from Clerk to Supabase Add subscriptions to your SaaS with Clerk Billing Getting started with Clerk Billing Multi-tenant analytics with Tinybird and Clerk How Huntr Migrated 250K Users to Clerk: A Scalable Auth Solution for Startups How to take Clerk to Production How to take your Clerk application to production A practical guide to testing Clerk Next.js applications Implementing multi-tenancy into a Supabase app with Clerk How Clerk integrates with a Next.js application using Supabase How Clerk integrates with Supabase Build a blog with tRPC, Prisma, Next.js and Clerk How to enrich PostHog events with Clerk user data How to build a secure project management platform with Next.js, Clerk, and Neon Validate your SaaS idea while building an audience Postmortem: February 6, 2025 service outage Implement Role-Based Access Control in Next.js 15 Build a Next.js sign-up form with React Hook Form How to implement Google authentication in Next.js 15 What is middleware in Next.js? How to customize Next.js metadata How to set environment variables in Node.js Building a React Login Page Template How to implement per-user OAuth scopes with Clerk Using Clerk SSO to access Google Calendar and other service data Streamline enterprise customer onboarding with SAML and Clerk Clerk launches EASIE SSO and eliminates SSO fees How to secure Liveblocks Rooms with Clerk in Next.js Securing Node.js Express APIs with Clerk and React Combining the benefits of session tokens and JWTs Build a task manager with Next.js, Supabase, and Clerk Comparing Clerk Webhooks vs Backend API Automate Neon schema changes with Drizzle and GitHub Actions A guide to reading authenticated user data from Clerk Role based access control with Clerk Organizations Mitigating OAuth’s recently discovered Open Response Type vulnerability Per-user B2B monetization with Stripe and Clerk Organizations Build a team-based task manager with Next.js, Neon, and Clerk Building a Hybrid Sign-Up/Subscribe Form with Stripe Elements Welcoming Colin from Zod as our inaugural Open Source Fellow Build a modern authenticated chat application with Next.js, Ably, and Clerk Build a waitlist with Clerk user metadata How to use Clerk with PostHog Identify in Next.js How to secure API Gateway using JWT and Lambda Authorizers with Clerk What are passkeys and how do they work? Comparing Authentication in React.js vs. Next.js How to Add an Onboarding Flow for your Application with Clerk Create Your Own Custom User Menu with Radix - Part 2 Introducing Webhook Workflows with Inngest & Svix Clerk raises $30M Series B from CRV and Stripe Clerk in 2023: A Year in Review Build a Movie Emoji Quiz App with Remix, Fauna, and Clerk Ultimate Guide to Magic Link Authentication Create Your Own Custom User Menu with Radix Introducing has(), protect(), and <Protect> Updated Pricing: 10,000 MAUs Free, and a new “Pro Plan” Next.js Authentication with Clerk: Streamlined SSR Handling Clerk Webhooks: Data Sync with Convex Exploring Clerk Metadata with Stripe Webhooks The Ultimate Guide to Next.js Authentication Empower Your Support Team With User Impersonation Clerk Webhooks: Getting Started A Complete Guide to Session Management in Next.js The Advanced Guide to Passwordless Authentication in Next.js How We Roll – Chapter 10: Roundup How We Roll – Chapter 9: Infrastructure Password-Based Authentication in Next.js
Build a Next.js login page template
Brian Morrison II · 2025-01-31 · via Clerk Blog

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.

Implementation overview

There are a set of common requirements when it comes to implementing session-based authentication in any application.

Database schema

At least two tables are required:

  • users - When users sign up, the application needs to at least store a user ID, username, and password so they can return in the future.
  • sessions - The sessions table tracks the information described in the previous section, allowing the application to look up a session by ID and determine the user it’s associated with.

Any tables with records associated with specific users will also need a userId or similar column added to make the association.

Backend changes

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.

Frontend changes

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

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.

Clerk for user management

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:

src/app/sign-in/[[...sign-in]]/page.tsx

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.

Introducing the demo project, Quillmate

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:

  • Next.js - The entire application is built with Next.js
  • Vercel - Since it is built with Next.js, it is easily deployable to Vercel.
  • OpenAI - The AI functionality utilizes OpenAI’s APIs.
  • Neon - All data is stored in a Postgres database provided by Neon.
  • Prisma - Prisma is the ORM used to talk to the database.

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.

Install new dependencies

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:

Updating the database schema

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:

prisma/schema.prisma

Run the following command in the terminal to update the Prisma client and push the changes to the Neon database:

Create the middleware

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:

src/middleware.ts

Creating the sign-up and login routes

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:

src/app/auth/actions.ts

Handling sign-up

Since validation.ts is the simplest of the three files, start by creating src/app/signup/validation.ts and paste in the following:

src/app/signup/validation.ts

Next, create the server actions file at src/app/signup/actions.ts and paste in the following:

src/app/signup/actions.ts

Finally, create src/app/signup/page.tsx and paste in the following:

src/app/signup/page.tsx

Handling sign-in

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:

src/app/signin/validation.ts

Next, create the server actions at src/app/signin/actions.ts and populate the file with the following:

src/app/signin/actions.ts

Then create the login page at src/app/signin/page.tsx and paste in the following:

src/app/signin/page.tsx

Associating articles with users

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:

prisma/schema.prisma

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:

src/app/articles/actions.ts

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:

src/app/articles/page.tsx

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:

src/app/page.tsx

Test it out!

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!

QuillMate Demo

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.

Neon Console

Conclusion

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!