



























Next.js has become the go-to framework for JavaScript and React development. It has become so popular because of the superior developer experience, performance optimization features, and its ability to facilitate different rendering options and serverless functions with ease. The combination of these attributes makes it an appealing choice for both new and experienced developers.
In Next.js 13, the Next.js team significantly upgraded the capabilities of the framework. Moving to what they call the “App Router,” Next.js is now based on React Server Components which boast performance upgrades over the previous client-server architecture.
But this shift has also led to a change in how authentication works in Next.js. In this article we want to provide an up-to-date guide on how authentication now works on Next.js so you can easily understand the concepts involved and easily add secure authentication to your Next.js applications.
The App Router paradigm was introduced in Next.js 13 and is a significant shift in how the Next.js framework works.
Next.js was initially built as a React framework to facilitate server-side rendered and statically generated sites. But as the framework grew, more options became available:
useState, useEffect, etc.) as you would in a regular React app.getStaticProps to fetch the required data at build time.getStaticProps, but this time you add a revalidate property. The revalidate interval (in seconds) determines how often the page should be updated.getServerSideProps to fetch data on each request.You could have some pages work with CSR, some SSG, and some SSR. But this also led to confusion and performance issues with sites not optimally built.
Next.js 13 and the App Router are designed to simplify the developer experience within Next.js, and rebuild the framework around React Server Components. With RSC, the default for the entire site is server-side rendering, with each page being opted-in to CSR as needed. This leads to performance gains, as rendering on the server is faster, and you don’t have to send heavy JavaScript payloads over the network for hydration. It also means more sites can work on the ‘edge’ network, where sites are served from multiple servers close to users.
But this does mean that the way developers have been using Next.js thus far has now changed. The old, Pages Router continues to work, and can be used side-by-side with the App Router, but significant changes in how data is served, such as no request/response objects being passed means developers will need to rethink how they work, and how their authentication works.
Here, we’re going to go through:
This will give you the ability to use either as you need, and to see the differences in each paradigm when it comes to authentication.
Before we get into authentication with the App Router, let’s look at how authentication works with the Pages Router in Next.js.
Let’s create a Next.js project. To do this, we use:
You will be prompted to choose different options, but given that we are explicitly using the Pages Router, you’ll want to select “no” when asked if you would like to use the App Router.
With that done, we can install Clerk:
Next, we want to add our API keys as environmental variables in an .env.local file. To get these, sign up for a free Clerk account:
Before we go any further, we’ll also make some small changes to our homepage, at pages/index.js:
If we now run npm run dev, we’ll get this homepage:

We’re now ready to start adding Clerk to our code. The first thing we need to do is mount the ClerkProvider. The ClerkProvider is the core component of Clerk. It is what handles all the active session data and the user context. Whenever a Clerk hook (or any other components) needs authentication data, it is getting it from the ClerkProvider.
The ClerkProvider needs needs to access headers to authenticate any user. This is important because:
To protect your entire application, it is recommended to wrap our main Component in the _app.tsx|jsx file:
This will protect every page within the application and will make the user context accessible anywhere within the app, but will also opt every page into dynamic rendering.
If you have statically served pages or are using incremental static regeneration, you can wrap route groups further into your application. For example, you might want to leave your marketing site unprotected, but wrap your dashboard components in the ClerkProvider.
Clerk requires middleware to determine the routes that need to be protected. This is in middleware.js in our root directory. This matcher will put every page and API route on the site behind authentication:
The entire application is now protected. Accessing any page while signed out will redirect you to the sign up page. If we go to the homepage again, we get redirected:

Usually, this isn’t what you want. Your homepage, product, and marketing pages aren’t very helpful if they are behind authentication!
If you navigate to the homepage now you’ll also get this warning:
To prevent this behavior, choose one of:
publicRoutes: ["/"] to authMiddlewareignoredRoutes: ["/((?!api|trpc))(_next.*|.+\\.[\\w]+$)", "/"] to authMiddlewareauthMiddleware, and replace Clerk’s default behavior of redirecting unless a route is included in public routesSo let’s make a change to add a public route:
Now, when we head to the homepage, it is available again:

Great. But now there is no way for us to sign up or sign in. Clerk’s Next.js Authentication SDK provides helpers for determining whether a user is signed in or note, and conditionally changing the text. Let’s wrap our text in these components:
Here, if a user is signed out, they’ll see a link to a sign up page. This page doesn’t exist yet, so lets create it. It will live at pages/sign-up/[[...index]].jsx:
Not much to it. If you try to go that page, you’ll be redirected to sign in/sign up, so it will look like its working. But you are actually being redirected because that page hasn’t been defined as a public route in the middleware, so it itself is behind authentication. To get around this, we’re actually going to add it to our environment variables as a special page:
Now, if we go to that sign up page, we’ll get the modal where we can sign up:

Then, as our environment variables say, we’re redirected to the home page:

As you can see, the link to sign in as gone, as it was wrapped in the component that only shows it if you are signed out.
We now have a problem. We are now signed in (great!), but we can’t sign out (uh oh!). We could create a specific link for this as well, but Clerk provides a UserButton component that allows us to do this easily. Let’s add that to the homepage:
We’ve wrapped this UserButton within the SignedIn component so it’ll only show when the user is signed in:

Using that button, the user can easily adjust their profile as well as sign out of the application.
Now the user is signed in, they can visit other pages. Let’s create a pages/protected.jsx page:
The code uses the clerkClient, getAuth, and buildClerkProps utilities from the @clerk/nextjs library to handle user authentication. If a user is not authenticated (determined by the absence of a user prop), the page prompts the user to log in. If authenticated, the page displays a personalized welcome message.
The server-side function getServerSideProps checks for the userId in the incoming request using the getAuth function; if the userId is present (indicating authentication), it fetches detailed user information from Clerk via clerkClient.users.getUser. The fetched data is then streamlined to a simpler format, extracting only necessary fields like the user’s first name and last name.
The getServerSideProps function concludes by returning the user data, if any, along with additional props sourced from buildClerkProps, ensuring the frontend receives the necessary data to render the page appropriately.
This renders as:

Here, the authentication is checked on the server before the page is rendered via getServerSideProps. We can also check whether the user is authenticated on the client. Let’s create a pages/protected-client.jsx page:
Which renders this page:

One final part of Next.js we can protect with authentication–API routes. With the pages router, any route within pages/api is returned as an API. Let’s protect an API route at pages/api/auth.js:
This uses the getAuth helper that retrieves the authentication state to protect the API route. If we call this within the browser, we’ll get the user JSON:

You now have a protected Next.js application using the pages router. Let’s move on to the App Router.
We’re now going to work through an entire example with the Next.js App Router. Some of this is the same as above, particularly, the set up, but once we get into the actual authentication, there are going to be some differences.
Let’s create a new Next.js project:
This time, when you are prompted to use the App Router, select “yes”.
Then install Clerk into this project:
And then add our API keys in an .env.local file:
We’ll spool up another bare-bones homepage, this time at app/page.js:
If we now run npm run dev, we’ll get this homepage:

Looks like we have some nicer default styling with the App Router.
Next up is to add the ClerkProvider. This is the first point at which there is a difference between the pages router and the App Router. With the App Router, we’re going to add the ClerkProvider to our layout.js:
The App Router doesn’t use the _app.js file. Instead, layout.js lets you set a global layout for your application. Therefore you can add the ClerkProvider to e.g. the dashboard/layout.js file, and only the files within that route group would require a login. To repeat from above, this is important because the ClerkProvider requires dynamic rendering. If you nest the ClerkProvider at a lower level, this allows you to serve the landing and marketing pages statically.
Next step is the middleware. Again, this is in middleware.js in our root directory. This time, we’ll start with our homepage as a public route:
Clerk is now protecting the entire application. Let’s change our homepage to use the SignedOut component so we can sign in to the app:
The link now shows on the page:

Next we’ll add the two other components that will be important for signing up/in/out. First, the sign up page, which will be at app/sign-up/[[...sign-up]]/page.jsx:
Remember to also add these new endpoints to your .env.local:
Second, we need the user button:
Now, when we click the sign up/in link we again go through to the Clerk modal:

Once we sign in we are redirected back to the homepage, now with the user button:

With the user signed in, let’s do the same as with the pages router: create a protected page and a protected API.
Again, for protected pages, we can check for authentication on the server or on the client. Let’s quickly do the client side as that is similar to the pages router:
The only difference between the App Router and the pages router version here is the “use client” directive. By default, all components in the App Router are server components, so will render on the server. The “use client” directive opts this component into client-side rendering, so we can then use Clerk hooks.
This renders as:

For server rendering, Clerk has two App Router-specific helpers that you can use with your Server Components:
Here, we’re going to use both to get information about the user on a protected page:
Which gives us a page with user information rendered:

For API routes, the routing is different, but the code is similar. Let’s build an API route under app/api/user/route.jsx:
We don’t have the request and response objects with the App Router, so get all our authentication data from our Clerk helpers (which get it from the ClerkProvider which gets it from the global scope via the Next.js headers() function). We can return a JSON of the user’s information:

And that’s it. You have server-side, client-side, and API route authentication using the Next.js App Router.
The Next.js App Router offers significant performance gains compared to the traditional pages router. However, you can absolutely continue leveraging the pages router in your Next.js applications – Clerk supports authentication with both routing approaches.
To learn more about the App Router, check out the official Next.js documentation. If you would like to get started with Clerk, sign up for a free account and follow along with our Next.js Quickstart.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。