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

推荐订阅源

Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
博客园 - 【当耐特】
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
D
Docker
GbyAI
GbyAI
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
The Cloudflare Blog
雷峰网
雷峰网
A
About on SuperTechFans
小众软件
小众软件
博客园 - Franky
博客园 - 聂微东
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
C
Check Point Blog
MongoDB | Blog
MongoDB | Blog
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
V2EX
Engineering at Meta
Engineering at Meta
宝玉的分享
宝玉的分享
aimingoo的专栏
aimingoo的专栏
量子位
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
罗磊的独立博客
Martin Fowler
Martin Fowler
D
DataBreaches.Net
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Secure Thoughts
Project Zero
Project Zero
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tailwind CSS Blog
S
Schneier on Security
Blog — PlanetScale
Blog — PlanetScale
The Hacker News
The Hacker News
Spread Privacy
Spread Privacy
Security Latest
Security Latest
NISL@THU
NISL@THU
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CXSECURITY Database RSS Feed - CXSecurity.com
J
Java Code Geeks

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) 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 Build a Next.js login page template 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
How do I add authentication to a Next.js app?
Brian Morrison II · 2025-09-15 · via Clerk Blog

Authentication is core to building any multi-user product, and it's important to get it right from the start.

There are a number of methods you can use when adding authentication into a product, and Next.js has its own paradigms to consider. Understanding the Next.js authentication strategies available is key to knowing which is best for your application, and properly implementing it is the next challenge.

In this article you'll learn about the most common authentication strategies, as well as how to add JWT authentication to a Next.js application.

Next.js authentication strategies: Choosing the right approach

There are many strategies to select from when planning your approach to authentication. The most common approaches are session token authentication, JWT-based authentication, and OAuth. Let's touch on how each of these compare.

Session tokens

Session token authentication is the oldest on this list but is still widely used today. When a user signs into an application using session token authentication, the backend service will verify the user's credentials against the database and, assuming they are valid, create an entity called a "session". Each session has some commonly tracked attributes stored such as the user it's associated with, when it was created, when it expires, and its status (valid, expired, etc). The session identifier is sent back to the user's device to be used with subsequent network requests.

The most common method of storing the session ID client-side is in a browser cookie so the ID is sent with future network requests automatically. When received by the server, the session is cross-referenced with the user for which it was created so that the server knows who is making the request and can apply security appropriately.

JWT

JSON Web Tokens (JWTs) are specially formatted strings that contain embedded information about a particular user or session and are cryptographically signed by the server. When a user signs in, the server will validate the user's credentials just like with session token authentication but instead of creating a session record (commonly in a database table), the details are encoded into a JWT and signed before being sent back to the client. The JWT is also sent with each request but since it contains the user and/or session details, the server does not have to look up those in the database. The server can simply verify the JWT signature is valid and can trust the encoded details if it is.

This has some benefits and drawbacks. One of the primary benefits is the speed by which requests are validated as no datastore lookups are required. Since verification is mostly performed on the receiving server, this also makes JWT authentication more scalable than session token authentication. As long as a server has a cached version of the signing secret (or public key in asymmetric signing configurations), that server can verify the JWTs authenticity.

The primary drawback is the lack of control if a JWT is leaked to an unauthorized party. Since all of the session information is embedded with the token and the verification process does not require any additional checks with a central datastore, there is no standard way to invalidate tokens once they've been signed and sent out.

OAuth

OAuth is a standard that allows a user to authenticate with one system and access multiple services using a single account. If you've ever signed into a web application with a Google or Apple account, you've used OAuth. In a typical configuration, the service provider (SP) will redirect users attempting to sign in to an identity provider (IdP) to supply their credentials and create a session. Once authenticated, the user's device will receive a code that can be provided to the SP, which will communicate with the IdP to verify the code, create the JWT, and send it back to the user.

This flow (known as the "Authorization Code Grant") describes how the SP and IdP work together to create the session and is only one of many flows that are part of the OAuth spec.

How to implement Next.js authentication with JWT tokens

Now that you have a solid understanding of some common authentication strategies, let's learn how to manually implement Next.js authentication using JWT tokens. To do this, you'll step through the following:

  • Configure a SQLite database to store user records
  • Set up public/private keys to sign and validate JWTs in a helper
  • Create sign-up and sign-in pages
  • Configure a Sign out button
  • Show claims from the JWT within a server-rendered page

To follow along, you'll need the following:

  • A general understanding of React, and ideally experience with Next.js
  • Node.js installed on your workstation

You'll use the supplied starter repository that is a Next.js application preconfigured with SQLite, a few shadcn/ui components, and a dashboard page with some dummy data. Through this guide, you'll create the sign-up page, sign-in page, sign-out button, and you'll configure the middleware to enforce authentication on the /dashboard route.

Upon signing in, the middleware will parse the JWT (stored as a cookie) to determine the user's authentication status. Server actions will be used throughout the various authentication functions.

The following dependencies are also pre-installed:

  • bcrypt to salt and hash user passwords before storing them in the database.
  • jose to create and validate JWTs

Before moving on, clone the start branch of this repository: clerk/nextjs-jwt-auth-demo. Once cloned, open the project in your code editor of choice and run pnpm install to install the dependencies.

Creating the SQLite and JWT helpers

You'll start by creating a helper file that lets the application interact with the SQLite database. The helper will create the connection, create the users table if it does not yet exist, and return a connection object to the caller. The table needed to support user authentication contains only three columns:

  • id is the unique identifier for the user
  • username is their username
  • password_hash is the salted and hashed representation of their password

Create the src/lib/db.ts and populate it with the following:

src/lib/db.ts

Next, you'll create the JWT helper file that contains the configuration for jose as well as the createToken function to generate a new JWT for the user and parseToken which verifies the token's validity and returns the claims (the data encoded within JWTs) to the caller if it is.

Create the src/lib/jwt.ts file and add the following:

src/lib/jwt.ts

Notice in the above code that the JWT_PRIVATE_KEY and JWT_PUBLIC_KEY are being referenced from the environment variables. To set this up, run the following command in your terminal to generate a key pair and set them in the .env.local file:

Inspecting the .env.local file will look similar to the following (albeit with a larger value for each variable):

.env.local

Building the sign-up flow

Before users can sign-in and use the application, they'll need a way to sign-up first. Create the src/app/actions.ts file to store the server actions required to sign-up. This configuration will check if a record with that username exists (responding with an error if found), creates the JWT and stores it as a cookie, and redirects the user to the /dashboard route.

src/app/actions.ts

Now create the src/app/sign-up/page.tsx file to store the sign-up form used to create an account:

src/app/sign-up/page.tsx

You can now start the application with npm run dev, access it using the provided URL, and navigate to the /sign-up route to create a user. After creating a user, you'll be redirected to the /dashboard route.

Configure sign-out

Since the JWT is stored in a cookie with the httpOnly flag, client-side JavaScript will not be able to access it, so you'll need to configure a server action to clear the cookie. Update the actions.ts file and append the signOut function as shown below:

src/app/actions.ts

Next, create a Sign Out button component at src/components/SignOutButton.tsx and paste in the following:

src/components/SignOutButton.tsx

Then you'll need to update the Navigation component to check if the user is logged in and render the button if they are. Since it is a server-rendered component, you can use the next/headers package to access the request cookies and the parseToken function to verify the user is signed in.

Update the src/components/Navigation.tsx file as follows:

src/components/Navigation.tsx

Now access the application in your browser once again and click the Sign out button in the navigation. You'll be redirected if you are on the /dashboard page and the navigation bar will update to show the Sign in and Sign up links.

Configure the sign-in page and actions

Now that sign-up and sign-out are working, you'll need a way for existing users to sign-in. Update the actions.ts file once again and append the following actions:

src/app/actions.ts

Then create the src/app/sign-in/page.tsx file to display the sign-in form:

src/app/sign-in/page.tsx

In the application, navigate to the /sign-in route and use the credentials you created earlier to sign-in and access the /dashboard route once again.

Protecting routes with Next.js authentication middleware

As of now, even unauthenticated users can access /dashboard if they enter the path in their browser. Next.js authentication middleware can be configured to intercept inbound requests and check the cookies to ensure a user is signed-in before allowing them to access protected routes. Furthermore, the middleware can also be configured to redirect unauthenticated users to /sign-in if they attempt to access /dashboard.

Create the src/middleware.ts file and populate it like so to achieve this protection:

src/middleware.ts

Display user information on the Dashboard page (optional)

Since the /dashboard route is protected by our Next.js authentication system, any users that can access it will have already signed in, meaning the information in the JWT can be trusted. The next/headers package can be used in page content just like in the Navigation.tsx component to parse details about the authenticated user and render the details on the page.

To do this, update src/app/dashboard/page.tsx as follows to display the user's username in the page header:

src/app/dashboard/page.tsx

Accessing the /dashboard page will now show the username in the welcome message!

Now what?

You now have a functional system that allows users to sign up and sign in to this demo app, however there are a number of missing, critical user management features:

  • Email address verification
  • Password reset functionality
  • Advanced attack protection and rate limiting
  • Session management and refresh tokens
  • Multi-factor authentication
  • Social login providers

These are just to name a few of the gaps. Production-ready authentication in Next.js goes well beyond basic JWT implementation, and this is where Clerk's Next.js authentication solution comes in.

Why choose Clerk for Next.js authentication?

Clerk is a complete user management platform that allows developers to add enterprise-grade Next.js authentication into their applications as quickly as possible. With Next.js applications, this can be done in just a few lines of code.

Once implemented, you'll automatically gain all of the features listed above along with many more such as:

  • One-click social authentication (Google, GitHub, Apple, etc.)
  • Simple multi-tenancy for B2B applications (including custom RBAC)
  • Subscription management with Clerk Billing
  • Advanced security features that protect against bots, brute force attacks, and abuse
  • Pre-built UI components that can be configured to match your application's design

Get started with production-ready Next.js authentication

If you're ready to implement a robust Next.js authentication solution for your Next.js application, check out our Next.js quickstart guide to learn how to get authentication added to your application in as little as 2 minutes. You'll have a complete, secure, and scalable authentication system without the complexity of building and maintaining it yourself.