Skip to main content

User Authentication

Authentication is the process of proving a user’s identity before granting them access to a resource. In this quickstart, you’ll learn how to bring Universal Login to your GenAI application and leverage OAuth 2.0 and OpenID Connect to securely authenticate users.

When a user authenticates with an identity provider through Auth0, Auth0 can pass user information in an ID token to an application or AI agent to deliver a personalized experience. For example, a chatbot can greet a user with their name and display relevant information based on the user's profile.

By the end of this quickstart, you should have an application that can:

  • Sign up and log in using a username and password or a Google account.
  • Authenticate and authorize users using OAuth 2.0 and OpenID Connect.
note

We value your feedback! To ask questions, report issues, or request new frameworks and providers, connect with us on GitHub.

Pick Your Tech Stack


Prerequisites

Before getting started, make sure you have completed the following steps:

unchecked

Create an Auth0 Account and a Dev Tenant

To continue with this quickstart, you need an Auth0 account and a Developer Tenant.

unchecked

Create Application

Create and configure a Regular Web Application to use with this quickstart.
To learn more about Auth0 applications, read ApplicationsArrow icon

Create Next.js app

Create a Next.js web application using Next.js version 15 or above. You can create a new application using create-next-app:

npx create-next-app@latest --src-dir
ctrl+C

Install dependencies

In the root directory of your project, install the Auth0 Next.js SDK:

npm i @auth0/nextjs-auth0
ctrl+C

Add login to your application

Secure the application using the Auth0 Next.js SDK.

1. Create your environment file

In the root directory of your project, create the .env.local file and add the following variables. If you created an application with this quickstart, Auth0 automatically populates your environment variables for you:

note

Your application’s client secret is masked for you. To get the client secret value, click the copy button on the code sample.

.env.local
ctrl+C
# .env.local
AUTH0_SECRET='use [openssl rand -hex 32] to generate a 32 bytes value'
APP_BASE_URL='http://localhost:3000'
AUTH0_DOMAIN='<your-auth0-domain>'
AUTH0_CLIENT_ID='<your-auth0-application-client-id>'
AUTH0_CLIENT_SECRET='<your-auth0-application-client-secret>'

2. Create the Auth0 client

Create a file at src/lib/auth0.ts and instantiate a new Auth0 client:

./src/lib/auth0.ts
ctrl+C
import { Auth0Client } from "@auth0/nextjs-auth0/server";

// Create an Auth0 Client.
export const auth0 = new Auth0Client();

The Auth0 client provides methods for handling authentication, sessions, and user data.

3. Add the authentication middleware

The middleware intercepts incoming requests and applies Auth0's authentication logic. Create the following file at src/middleware.ts:

./src/middleware.ts
ctrl+C
import { NextRequest, NextResponse } from "next/server";
import { auth0 } from "./lib/auth0";

export async function middleware(request: NextRequest) {
const authRes = await auth0.middleware(request);

// Authentication routes — let the Auth0 middleware handle it.
if (request.nextUrl.pathname.startsWith('/auth')) {
return authRes;
}

const { origin } = new URL(request.url);
const session = await auth0.getSession();

// User does not have a session — redirect to login.
if (!session) {
return NextResponse.redirect(`${origin}/auth/login`);
}
return authRes;
}

export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image, images (image optimization files)
* - favicon.ico, sitemap.xml, robots.txt (metadata files)
* - $ (root)
*/
'/((?!_next/static|_next/image|images|favicon.[ico|png]|sitemap.xml|robots.txt|$).*)',
],
};

Update the src/app/page.tsx file to display content based on the user session:

./src/app/page.tsx
ctrl+C
"use client";

import { useUser } from "@auth0/nextjs-auth0";

export default function Page() {
// Extract the user object and loading state from Auth0.
const { user, isLoading } = useUser();

if (isLoading) return <div>Loading...</div>;

// If no user, show sign-up and login buttons.
if (!user) {
return (
<main className="flex flex-col items-center justify-center h-screen p-10">
<a href="/auth/login?screen_hint=signup">
<button>Sign up</button>
</a>
<a href="/auth/login">
<button>Log in</button>
</a>
</main>
);
}

// If user exists, show a welcome message and logout button.
return (
<main className="flex flex-col items-center justify-center h-screen p-10">
<h1>Welcome, {user.name}!</h1>
<p>
<a href="/auth/logout">
<button>Log out</button>
</a>
</p>
</main>
);
}

The app displays the Sign up or Log in buttons without a user session. If a user session exists, the app displays a welcome message with the user's name and a Log out button.

Run your application

Run this command to start your server:

npm run dev
ctrl+C

Visit the URL http://localhost:3000 in your browser.

You will see:

Auth0 login screen

  • A Sign up and Log in button if the user is not authenticated.
  • A welcome message and a Log out button if the user is authenticated.

Explore the example app on GitHub.


Prerequisites

Before getting started, make sure you have completed the following steps:

unchecked

Create an Auth0 Account and a Dev Tenant

To continue with this quickstart, you need an Auth0 account and a Developer Tenant.

unchecked

Create Application

Create and configure a Regular Web Application to use with this quickstart.
To learn more about Auth0 applications, read ApplicationsArrow icon

Create Python app

Set up an interactive CLI application with FastAPI and the Auth0 Python SDK.

To create a new Python app, use Python version 3.12 and above.

Install dependencies

In the root directory of your project, install the following dependencies:

  • fastapi: FastAPI web framework for building APIs with Python.
  • auth0-server-python: Auth0 Server Python SDK for implementing user authentication in Python applications.
  • openai: OpenAI Python client for accessing the API.
  • google-api-python-client: Google API client library for Python.
  • uvicorn and python-dotenv: Other Python utility libraries.
pip3 install fastapi auth0-server-python openai google-api-python-client uvicorn python-dotenv
ctrl+C

Add login to your application

Secure the application using the Auth0 Python SDK.

1. Create your environment file

In the root directory of your project, create the .env.local file and add the following variables. If you created an application with this quickstart, Auth0 automatically populates your environment variables for you:

note

Your application’s client secret is masked for you. To get the client secret value, click the copy button on the code sample.

.env.local
ctrl+C
# .env.local
AUTH0_SECRET='use [openssl rand -hex 32] to generate a 32 bytes value'
APP_BASE_URL='http://localhost:3000'
AUTH0_DOMAIN='<your-auth0-domain>'
AUTH0_CLIENT_ID='<your-auth0-application-client-id>'
AUTH0_CLIENT_SECRET='<your-auth0-application-client-secret>'

To initialize your local Python environment, run the following commands in your terminal:

python3 -m venv env
source env/bin/activate
ctrl+C

2. Create the Auth0 client

Create a file at src/app.py and add the following code to instantiate a new Auth0 client.

When you initialize the Auth0 client, you need to specify additional authorization parameters to enable your application to retrieve access tokens for a supported identity provider:

ParameterDescription
scopeRequests the following Auth0 scopes to be authorized for the application:

  • openid: (Required) Indicates that the application intends to use OIDC to verify the user's identity. To learn more read OpenID connect scopes.
  • profile: Returns claims that represent basic profile information, including name, family_name, given_name, middle_name, nickname, picture, and updated_at.
  • email: Returns the email claim, which contains the user's email address, and email_verified, which is a boolean indicating whether the email address was verified by the user.
  • offline_access: Requests an Auth0 refresh token from the Auth0 Authorization Server, which will be exchanged for a new access token from the requested connection's Token Vault. To learn more, read Token Vault.

./src/app.py
ctrl+C
# import dependencies
from fastapi import FastAPI, Request, Response
from fastapi.responses import HTMLResponse
from auth0_server_python.auth_server import ServerClient
from asyncio import sleep
from dotenv import load_dotenv
import uvicorn
import threading
import asyncio
import os
import webbrowser

load_dotenv(dotenv_path=".env.local")

class MemoryTransactionStore:
def __init__(self):
self.store = {}

async def set(self, key, value, options=None):
self.store[key] = value

async def get(self, key, options=None):
return self.store.get(key)

async def delete(self, key, options=None):
if key in self.store:
del self.store[key]

auth0 = ServerClient(
domain=os.getenv("AUTH0_DOMAIN"),
client_id=os.getenv("AUTH0_CLIENT_ID"),
client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
secret=os.getenv("AUTH0_SECRET"),
redirect_uri=os.getenv("APP_BASE_URL") + "/auth/callback",
transaction_store=MemoryTransactionStore(),
state_store=MemoryTransactionStore(),
authorization_params={
"scope": "openid profile email offline_access",
}
)

The Auth0 client provides methods for handling authentication, sessions, and user data.

3. Instantiate FastAPI instance

In src/app.py, instantiate a FastAPI instance that intercepts incoming requests and applies Auth0's authentication logic:

./src/app.py
ctrl+C
# ...

app = FastAPI()

@app.get("/auth/callback", response_class=HTMLResponse)
async def callback(request: Request):
result = await auth0.complete_interactive_login(str(request.url))
if result.get("error"):
return {"error": result.get("error")}
else:
user = result.get("state_data").get("user")
return f"""
<html>
<head>
<title>Login Successful</title>
<script>
function closeWindow() {{
window.close();
}}
</script>
</head>
<body>
<h2>Login Successful!</h2>
<p>Successful for: {user}</p>
<h3>You can now close this window.</h3>
<button onclick="closeWindow()">Close Window</button>
</body>
</html>
"""

if __name__ == "__main__":
server_thread = threading.Thread(
target=uvicorn.run,
args=(app,),
kwargs={"host": "127.0.0.1", "port": 3000, "log_level": "warning"},
daemon=True,
)
server_thread.start()

4. Add login through the browser

Add the following code to src/app.py to ask the user to log in from a browser window:

./src/app.py
ctrl+C
# ...

print("-" * 25)
print("Please log in to your account.")
print("Opening browser for authentication...")
print("-" * 25)

async def wait_for_user():
webbrowser.open(await auth0.start_interactive_login())
while True:
user = await auth0.get_user()
if user:
break
await sleep(0.5)
return user

user = asyncio.run(wait_for_user())
print("Log in successful for:", user.get("name"))
print("-" * 25)

Run your application

Run this command to start your server:

python3 src/app.py
ctrl+C

Visit the URL http://localhost:3000 in your browser.

Next steps