Auth0 Authentication API — Programmatic Login and User Management
In this tutorial, you will learn about Auth0 Authentication API. We cover key concepts, practical examples, and best practices to help you master this topic.
The Auth0 Authentication API provides programmatic access to authenticate users, exchange authorization codes for tokens, handle refresh tokens, manage user profiles, and query user information.
What You'll Learn
By the end of this lesson you will use the Authentication API endpoints to implement custom login flows, handle token exchange and refresh, fetch user profiles, and manage sessions.
Why It Matters
The Authentication API gives you full control over the auth flow for server-side applications, custom login UIs, and backend services where Universal Login's redirect flow is not suitable.
Real-World Use
DodaZIP uses the Authentication API for server-side token validation. When a backend service receives a request, it calls the /userinfo endpoint to verify the token is valid and fetch the user's profile.
flowchart LR
A[Client App] -->|Authorization Code| B[Auth0 /oauth/token]
B -->|Access Token| A
A -->|API Call| C[Backend Service]
C -->|Validate Token| D[Auth0 /userinfo]
D -->|User Profile| C
style B fill:#eb5424,color:#fff
Authentication Endpoints
Key endpoints for programmatic authentication.
# auth_endpoints.py
# Key Authentication API endpoints
def auth_api_endpoints():
endpoints = {
"/authorize": "Initiates the authentication flow, redirects to login",
"/oauth/token": "Exchanges authorization code for tokens",
"/oauth/token": "Also used for refresh token and client credentials",
"/userinfo": "Returns user profile for a valid access token",
"/dbconnections/signup": "Creates a new user in the database connection",
"/dbconnections/change_password": "Triggers password change email",
"/passwordless/start": "Starts passwordless authentication",
"/users/{id}": "Fetches or updates a specific user profile",
}
print("Authentication API Endpoints:")
for endpoint, desc in endpoints.items():
print(f" {endpoint:45s} {desc}")
auth_api_endpoints()
Token Exchange
Exchange an authorization code for tokens.
# POST /oauth/token
curl --request POST \
--url 'https://YOUR_TENANT.us.auth0.com/oauth/token' \
--header 'content-type: application/json' \
--data '{
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "AUTHORIZATION_CODE",
"redirect_uri": "https://yourapp.com/callback"
}'
# token_exchange.py
# Exchange authorization code for tokens
import requests
import os
def exchange_code(auth_code):
domain = os.getenv("AUTH0_DOMAIN", "your-tenant.us.auth0.com")
client_id = os.getenv("AUTH0_CLIENT_ID", "your-client-id")
client_secret = os.getenv("AUTH0_CLIENT_SECRET", "your-client-secret")
response = requests.post(
f"https://{domain}/oauth/token",
json={
"grant_type": "authorization_code",
"client_id": client_id,
"client_secret": client_secret,
"code": auth_code,
"redirect_uri": "https://dodatech.app/callback",
}
)
if response.status_code == 200:
tokens = response.json()
print("Token exchange successful")
print(f" Access token: {tokens['access_token'][:20]}...")
print(f" ID token: {tokens.get('id_token', 'N/A')[:20]}...")
print(f" Expires in: {tokens['expires_in']} seconds")
if "refresh_token" in tokens:
print(f" Refresh token: {tokens['refresh_token'][:20]}...")
return tokens
else:
print(f"Token exchange failed: {response.text}")
return None
exchange_code("sample_auth_code_123")
Refreshing Tokens
Use refresh tokens to maintain sessions.
# refresh_token.py
# Session management with refresh tokens
def refresh_session(refresh_token):
domain = os.getenv("AUTH0_DOMAIN", "your-tenant.us.auth0.com")
client_id = os.getenv("AUTH0_CLIENT_ID", "your-client-id")
client_secret = os.getenv("AUTH0_CLIENT_SECRET", "your-client-secret")
response = requests.post(
f"https://{domain}/oauth/token",
json={
"grant_type": "refresh_token",
"client_id": client_id,
"client_secret": client_secret,
"refresh_token": refresh_token,
}
)
if response.status_code == 200:
tokens = response.json()
print("Session refreshed")
print(f" New access token: {tokens['access_token'][:20]}...")
print(f" New refresh token: {tokens.get('refresh_token', 'N/A')[:20]}...")
return tokens
else:
print(f"Refresh failed: {response.text}")
return None
refresh_session("sample_refresh_token_123")
User Profile
Fetch user profile information with the access token.
# user_profile.py
# Fetch user profile
def get_user_profile(access_token):
domain = os.getenv("AUTH0_DOMAIN", "your-tenant.us.auth0.com")
response = requests.get(
f"https://{domain}/userinfo",
headers={"Authorization": f"Bearer {access_token}"}
)
if response.status_code == 200:
profile = response.json()
print("User Profile:")
print(f" Sub (ID): {profile.get('sub')}")
print(f" Name: {profile.get('name')}")
print(f" Email: {profile.get('email')}")
print(f" Email verified: {profile.get('email_verified')}")
print(f" Picture: {profile.get('picture')}")
return profile
else:
print(f"Failed to get profile: {response.text}")
return None
get_user_profile("sample_access_token_123")
Common Mistakes
Not validating tokens on the server: Always validate tokens (signature, expiry, audience) on your backend. Trusting unvalidated tokens is a critical vulnerability.
Storing refresh tokens in localStorage: Refresh tokens should be stored in httpOnly cookies, not accessible to JavaScript, to prevent XSS Attacks.
Exchanging the authorization code multiple times: An authorization code is single-use. Attempting to reuse it returns an error.
Not using PKCE for public clients: SPAs and mobile apps should use PKCE to prevent authorization code interception attacks.
Forgetting to handle token expiry: Access tokens expire. Implement automatic token refresh in your client or redirect to login when expired.
Practice Questions
What is the /oauth/token endpoint used for? Exchanging authorization codes, refresh tokens, and client credentials for access tokens.
How do you refresh an expired access token? POST to /oauth/token with grant_type=refresh_token and the refresh token.
What does the /userinfo endpoint return? The user's profile information including sub, name, email, and picture.
Why should you validate tokens on the server? To verify the token signature, check expiration, and ensure the audience matches your API.
Challenge: Create a Python script that performs a complete authentication flow: exchange a code for tokens, fetch the user profile, and handle token refresh.
FAQ
Mini Project
Create a token management service that stores tokens securely, handles automatic refresh, and provides a getValidToken() method that always returns a fresh access token.
class TokenManager:
def __init__(self, domain, client_id, client_secret):
self.domain = domain
self.client_id = client_id
self.client_secret = client_secret
self.access_token = None
self.refresh_token = None
self.expires_at = 0
async def get_valid_token(self):
import time
if time.time() >= self.expires_at and self.refresh_token:
await self.refresh()
return self.access_token
async def refresh(self):
response = requests.post(
f"https://{self.domain}/oauth/token",
json={
"grant_type": "refresh_token",
"client_id": self.client_id,
"client_secret": self.client_secret,
"refresh_token": self.refresh_token,
}
)
data = response.json()
self.access_token = data["access_token"]
self.expires_at = __import__("time").time() + data["expires_in"]
manager = TokenManager("tenant.us.auth0.com", "client_id", "client_secret")
print(f"Token manager initialized with domain: {manager.domain}")
What's Next
Next: Social Connections for social login.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro