
Research
/Security News
60 Malicious Ruby Gems Used in Targeted Credential Theft Campaign
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
@auth0/nextjs-auth0
Advanced tools
@auth0/nextjs-auth0 is a library that provides authentication and authorization for Next.js applications using Auth0. It simplifies the process of integrating Auth0 into Next.js apps by providing a set of tools and utilities for handling user sessions, protecting routes, and managing user profiles.
User Authentication
This feature allows you to handle user authentication with Auth0. The `handleAuth` function sets up the necessary routes for login, logout, and callback.
const { handleAuth } = require('@auth0/nextjs-auth0');
export default handleAuth();
Protecting API Routes
This feature allows you to protect API routes by ensuring that only authenticated users can access them. The `withApiAuthRequired` function wraps your API route handler to enforce authentication.
import { withApiAuthRequired } from '@auth0/nextjs-auth0';
export default withApiAuthRequired((req, res) => {
res.status(200).json({ message: 'This is a protected API route' });
});
Protecting Pages
This feature allows you to protect Next.js pages by ensuring that only authenticated users can access them. The `withPageAuthRequired` function wraps your page component to enforce authentication.
import { withPageAuthRequired } from '@auth0/nextjs-auth0';
const ProtectedPage = () => {
return <div>This is a protected page</div>;
};
export default withPageAuthRequired(ProtectedPage);
Fetching User Profile
This feature allows you to fetch and display the authenticated user's profile information. The `useUser` hook provides the user's data, loading state, and any errors.
import { useUser } from '@auth0/nextjs-auth0';
const UserProfile = () => {
const { user, error, isLoading } = useUser();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>{error.message}</div>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
};
export default UserProfile;
next-auth is a complete open-source authentication solution for Next.js applications. It supports multiple authentication providers, including OAuth, email/password, and custom credentials. Compared to @auth0/nextjs-auth0, next-auth offers more flexibility in terms of provider options and customization but may require more configuration.
Firebase provides a suite of tools for building and managing web and mobile applications, including authentication. Firebase Authentication supports various authentication methods, such as email/password, phone, and social providers. Compared to @auth0/nextjs-auth0, Firebase offers a broader range of services beyond authentication, such as real-time databases and cloud functions, but may be more complex to integrate into a Next.js application.
Passport is a popular authentication middleware for Node.js. It supports a wide range of authentication strategies, including OAuth, OpenID, and custom strategies. Compared to @auth0/nextjs-auth0, Passport provides more granular control over the authentication process but requires more setup and configuration.
npm i @auth0/nextjs-auth0
Add the following environment variables to your .env.local
file:
AUTH0_DOMAIN=
AUTH0_CLIENT_ID=
AUTH0_CLIENT_SECRET=
AUTH0_SECRET=
APP_BASE_URL=
The AUTH0_DOMAIN
, AUTH0_CLIENT_ID
, and AUTH0_CLIENT_SECRET
can be obtained from the Auth0 Dashboard once you've created an application. This application must be a Regular Web Application
.
The AUTH0_SECRET
is the key used to encrypt the session and transaction cookies. You can generate a secret using openssl
:
openssl rand -hex 32
The APP_BASE_URL
is the URL that your application is running on. When developing locally, this is most commonly http://localhost:3000
.
[!IMPORTANT]
You will need to register the follwing URLs in your Auth0 Application via the Auth0 Dashboard:
- Add
http://localhost:3000/auth/callback
to the list of Allowed Callback URLs- Add
http://localhost:3000/auth/logout
to the list of Allowed Logout URLs
Create an instance of the Auth0 client. This instance will be imported and used in anywhere we need access to the authentication methods on the server.
Add the following contents to a file named lib/auth0.ts
:
import { Auth0Client } from "@auth0/nextjs-auth0/server"
export const auth0 = new Auth0Client()
Create a middleware.ts
file in the root of your project's directory:
import type { NextRequest } from "next/server"
import { auth0 } from "./lib/auth0"
export async function middleware(request: NextRequest) {
return await auth0.middleware(request)
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico, sitemap.xml, robots.txt (metadata files)
*/
"/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
],
}
[!NOTE]
If you're using asrc/
directory, themiddleware.ts
file must be created inside thesrc/
directory.
You can now begin to authenticate your users by redirecting them to your application's /auth/login
route:
import { auth0 } from "@/lib/auth0"
export default async function Home() {
const session = await auth0.getSession()
if (!session) {
return (
<main>
<a href="/auth/login?screen_hint=signup">Sign up</a>
<a href="/auth/login">Log in</a>
</main>
)
}
return (
<main>
<h1>Welcome, {session.user.name}!</h1>
</main>
)
}
[!IMPORTANT]
You must use<a>
tags instead of the<Link>
component to ensure that the routing is not done client-side as that may result in some unexpected behavior.
You can customize the client by using the options below:
Option | Type | Description |
---|---|---|
domain | string | The Auth0 domain for the tenant (e.g.: example.us.auth0.com ). If it's not specified, it will be loaded from the AUTH0_DOMAIN environment variable. |
clientId | string | The Auth0 client ID. If it's not specified, it will be loaded from the AUTH0_CLIENT_ID environment variable. |
clientSecret | string | The Auth0 client secret. If it's not specified, it will be loaded from the AUTH0_CLIENT_SECRET environment variable. |
authorizationParameters | AuthorizationParameters | The authorization parameters to pass to the /authorize endpoint. See Passing authorization parameters for more details. |
appBaseUrl | string | The URL of your application (e.g.: http://localhost:3000 ). If it's not specified, it will be loaded from the APP_BASE_URL environment variable. |
secret | string | A 32-byte, hex-encoded secret used for encrypting cookies. If it's not specified, it will be loaded from the AUTH0_SECRET environment variable. |
signInReturnToPath | string | The path to redirect the user to after successfully authenticating. Defaults to / . |
session | SessionConfiguration | Configure the session timeouts and whether to use rolling sessions or not. See Session configuration for additional details. |
beforeSessionSaved | BeforeSessionSavedHook | A method to manipulate the session before persisting it. See beforeSessionSaved for additional details. |
onCallback | OnCallbackHook | A method to handle errors or manage redirects after attempting to authenticate. See onCallback for additional details. |
sessionStore | SessionStore | A custom session store implementation used to persist sessions to a data store. See Database sessions for additional details. |
There are 2 ways to customize the authorization parameters that will be passed to the /authorize
endpoint. The first option is through static configuration when instantiating the client, like so:
export const auth0 = new Auth0Client({
authorizationParameters: {
scope: "openid profile email",
audience: "urn:custom:api",
},
})
The second option is through the query parameters to the /auth/login
endpoint which allows you to specify the authorization parameters dynamically. For example, to specify an audience
, the login URL would look like so:
<a href="/auth/login?audience=urn:my-api">Login</a>
To access the currently authenticated user on the client, you can use the useUser()
hook, like so:
"use client"
import { useUser } from "@auth0/nextjs-auth0"
export default function Profile() {
const { user, isLoading, error } = useUser()
if (isLoading) return <div>Loading...</div>
return (
<main>
<h1>Profile</h1>
<div>
<pre>{JSON.stringify(user, null, 2)}</pre>
</div>
</main>
)
}
On the server, the getSession()
helper can be used in Server Components, Server Routes, Server Actions, and middleware to get the session of the currently authenticated user and to protect resources, like so:
import { auth0 } from "@/lib/auth0"
export default async function Home() {
const session = await auth0.getSession()
if (!session) {
return <div>Not authenticated</div>
}
return (
<main>
<h1>Welcome, {session.user.name}!</h1>
</main>
)
}
On the server, the getSession(req)
helper can be used in getServerSideProps
, API routes, and middleware to get the session of the currently authenticated user and to protect resources, like so:
import type { GetServerSideProps, InferGetServerSidePropsType } from "next"
import { auth0 } from "@/lib/auth0"
export const getServerSideProps = (async (ctx) => {
const session = await auth0.getSession(ctx.req)
if (!session) return { props: { user: null } }
return { props: { user: session.user ?? null } }
}) satisfies GetServerSideProps<{ user: any | null }>
export default function Page({
user,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
if (!user) {
return (
<main>
<p>Not authenticated!</p>
</main>
)
}
return (
<main>
<p>Welcome, {user.name}!</p>
</main>
)
}
The getAccessToken()
helper can be used both in the browser and on the server to obtain the access token to call external APIs. If the access token has expired and a refresh token is available, it will automatically be refreshed and persisted.
To obtain an access token to call an external API on the client, you can use the getAccessToken()
helper, like so:
"use client"
import { getAccessToken } from "@auth0/nextjs-auth0"
export default function Component() {
async function fetchData() {
const token = await getAccessToken()
// call external API with the token...
}
return (
<main>
<button onClick={fetchData}>Fetch Data</button>
</main>
)
}
On the server, the getAccessToken()
helper can be used in Server Components, Server Routes, Server Actions, and middleware to get an access token to call external APIs, like so:
import { NextResponse } from "next/server"
import { auth0 } from "@/lib/auth0"
export async function GET() {
const token = await auth0.getAccessToken()
// call external API with token...
return NextResponse.json({
message: "Success!",
})
}
On the server, the getAccessToken(req)
helper can be used in getServerSideProps
, API routes, and middleware to get an access token to call external APIs, like so:
import type { NextApiRequest, NextApiResponse } from "next"
import { auth0 } from "@/lib/auth0"
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<{ message: string }>
) {
const token = await auth0.getAccessToken(req)
// call external API with token...
res.status(200).json({ message: "Success!" })
}
The SDK exposes hooks to enable you to provide custom logic that would be run at certain lifecycle events.
beforeSessionSaved
The beforeSessionSaved
hook is run right before the session is persisted. It provides a mechanism to modify the session claims before persisting them.
The hook recieves a SessionData
object and must return a Promise that resolves to a SessionData
object: (session: SessionData) => Promise<SessionData>
. For example:
export const auth0 = new Auth0Client({
async beforeSessionSaved(session) {
return {
...session,
user: {
...session.user,
foo: "bar",
},
}
},
})
onCallback
The onCallback
hook is run once the user has been redirected back from Auth0 to your application with either an error or the authorization code which will be verified and exchanged.
The onCallback
hook receives 3 parameters:
error
: the error returned from Auth0 or when attempting to complete the transaction. This will be null
if the transaction was completed successfully.context
: provides context on the transaction that initiated the transaction.session
: the SessionData
that will be persisted once the transaction completes successfully. This will be null
if there was an error.The hook must return a Promise that resolves to a NextResponse
.
For example, a custom onCallback
hook may be specified like so:
export const auth0 = new Auth0Client({
async onCallback(error, context, session) {
// redirect the user to a custom error page
if (error) {
return NextResponse.redirect(
new URL(`/error?error=${error.message}`, process.env.APP_BASE_URL)
)
}
// complete the redirect to the provided returnTo URL
return NextResponse.redirect(
new URL(context.returnTo || "/", process.env.APP_BASE_URL)
)
},
})
The session configuration can be managed by specifying a session
object when configuring the Auth0 client, like so:
export const auth0 = new Auth0Client({
session: {
rolling: true,
absoluteDuration: 60 * 60 * 24 * 30, // 30 days in seconds
inactivityDuration: 60 * 60 * 24 * 7, // 7 days in seconds
},
})
Option | Type | Description |
---|---|---|
rolling | boolean | When enabled, the session will continue to be extended as long as it is used within the inactivity duration. Once the upper bound, set via the absoluteDuration , has been reached, the session will no longer be extended. Default: true . |
absoluteDuration | number | The absolute duration after which the session will expire. The value must be specified in seconds. Default: 30 days . |
inactivityDuration | number | The duration of inactivity after which the session will expire. The value must be specified in seconds. Default: 7 days . |
By default, the user's sessions are stored in encrypted cookies. You may choose to persist the sessions in your data store of choice.
To do this, you can provide a SessionStore
implementation as an option when configuring the Auth0 client, like so:
export const auth0 = new Auth0Client({
sessionStore: {
async get(id) {
// query and return a session by its ID
},
async set(id, sessionData) {
// upsert the session given its ID and sessionData
},
async delete(id) {
// delete the session using its ID
},
},
})
The SDK mounts 5 routes:
/auth/login
: the login route that the user will be redirected to to start a initiate an authentication transaction/auth/logout
: the logout route that must be addedto your Auth0 application's Allowed Logout URLs/auth/callback
: the callback route that must be addedto your Auth0 application's Allowed Callback URLs/auth/profile
: the route to check the user's session and return their attributes/auth/access-token
: the route to check the user's session and return an access token (which will be automatically refreshed if a refresh token is available)v4.0.0-alpha.0 (2024-10-23)
FAQs
Auth0 Next.js SDK
The npm package @auth0/nextjs-auth0 receives a total of 249,206 weekly downloads. As such, @auth0/nextjs-auth0 popularity was classified as popular.
We found that @auth0/nextjs-auth0 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 42 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isn’t whitelisted.