
Auth0 Express
Wire Auth0 OpenID Connect login, logout, and protected routes into an Express app with optional EJS views.
Overview
auth0-express is an agent skill for the Build phase that guides Express.js integration with Auth0 OIDC middleware, protected routes, and login/logout UX patterns.
Install
npx skills add https://github.com/auth0/agent-skills --skill auth0-expressWhat is this skill?
- EJS template pattern with isAuthenticated, user profile, and login/logout links
- requiresAuth() guard on routes like /dashboard
- Custom login with returnTo for post-auth redirects
- req.oidc user, idToken, and idTokenClaims access on protected handlers
Adoption & trust: 597 installs on skills.sh; 26 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have an Express app but no repeatable recipe for Auth0 sessions, protected pages, and showing the logged-in user in templates.
Who is it for?
Indie builders adding hosted auth to an existing Express codebase before shipping a customer-facing dashboard.
Skip if: Teams that only need SPA PKCE without Express, or projects that have already standardized on a different IdP with approved middleware.
When should I use this skill?
Building or extending an Express server that should use Auth0 for login, logout, and authenticated route access.
What do I get? / Deliverables
Your agent produces working /login, /logout, guarded routes, and EJS (or similar) views that read req.oidc user state.
- Login and logout route handlers
- Protected routes using requiresAuth()
- View or API handlers reading req.oidc user and tokens
Recommended Skills
Journey fit
Authentication wiring belongs in the Build phase when you connect identity to your server and session middleware. Auth0 Express is a third-party identity integration, not generic CRUD—canonical shelf is integrations.
How it compares
Use for procedural Express+Auth0 wiring instead of asking the agent to invent OAuth routes from scratch each time.
Common Questions / FAQ
Who is auth0-express for?
Solo and indie builders using Express who want Auth0 login, logout, and route guards documented as copy-paste-ready patterns for their agent.
When should I use auth0-express?
During Build integrations when you add Auth0 to Express—especially when you need EJS pages, dashboard returnTo login, or JSON user-info endpoints on protected routes.
Is auth0-express safe to install?
Review the Security Audits panel on this Prism page and treat Auth0 client secrets and callback URLs as sensitive; the skill describes network auth flows your app must configure correctly.
SKILL.md
READMESKILL.md - Auth0 Express
## Common Patterns ### Template Rendering with EJS **Install EJS:** ```bash npm install ejs ``` **Configure:** ```javascript app.set('view engine', 'ejs'); ``` **Create `views/index.ejs`:** ```html <!DOCTYPE html> <html> <head> <title>My Auth0 App</title> </head> <body> <% if (isAuthenticated) { %> <h1>Welcome, <%= user.name %>!</h1> <img src="<%= user.picture %>" alt="<%= user.name %>" /> <p><%= user.email %></p> <a href="/logout">Logout</a> <% } else { %> <h1>Please log in</h1> <a href="/login">Login</a> <% } %> </body> </html> ``` **Update route:** ```javascript app.get('/', (req, res) => { res.render('index', { isAuthenticated: req.oidc.isAuthenticated(), user: req.oidc.user }); }); ``` --- ### Custom Login with Return URL ```javascript app.get('/dashboard', requiresAuth(), (req, res) => { res.render('dashboard', { user: req.oidc.user }); }); // Login redirects to dashboard after authentication app.get('/login-to-dashboard', (req, res) => { res.oidc.login({ returnTo: '/dashboard' }); }); ``` --- ### Access User Information ```javascript app.get('/user-info', requiresAuth(), (req, res) => { // User profile const user = req.oidc.user; // Check if authenticated const isAuth = req.oidc.isAuthenticated(); // ID token const idToken = req.oidc.idToken; // ID token claims const idTokenClaims = req.oidc.idTokenClaims; res.json({ user, isAuthenticated: isAuth, idToken: idToken }); }); ``` --- ### Call External APIs ```javascript app.get('/call-api', requiresAuth(), async (req, res) => { try { // Extract the token string from the access token object const { access_token } = req.oidc.accessToken; const response = await fetch('https://your-api.com/data', { headers: { Authorization: `Bearer ${access_token}` } }); const data = await response.json(); res.json(data); } catch (error) { res.status(500).json({ error: error.message }); } }); ``` **Note:** To call APIs, add `authorizationParams` to middleware config: ```javascript app.use(auth({ authRequired: false, auth0Logout: true, secret: process.env.SECRET, baseURL: process.env.BASE_URL, clientID: process.env.CLIENT_ID, issuerBaseURL: process.env.ISSUER_BASE_URL, clientSecret: process.env.CLIENT_SECRET, authorizationParams: { response_type: 'code', audience: 'https://your-api-identifier', // Add this scope: 'openid profile email' } })); ``` --- ### Custom Logout Redirect ```javascript app.get('/custom-logout', (req, res) => { res.oidc.logout({ returnTo: 'https://your-app.com/goodbye' }); }); ``` --- ### Conditional Authentication ```javascript // Protect specific routes app.get('/admin', requiresAuth(), (req, res) => { // Only authenticated users can access res.render('admin', { user: req.oidc.user }); }); // Optional authentication (check manually) app.get('/home', (req, res) => { if (req.oidc.isAuthenticated()) { res.render('home-auth', { user: req.oidc.user }); } else { res.render('home-public'); } }); ``` --- ## Configuration Options ### Complete Middleware Configuration ```javascript app.use(auth({ authRequired: false, // Don't require auth globally auth0Logout: true, // Enable logout route secret: process.env.SECRET, baseURL: process.env.BASE_URL, clientID: process.env.CLIENT_ID, issuerBaseURL: process.env.ISSUER_BASE_URL, clientSecret: process.env.CLIENT_SECRET, // Authorization parameters authorizationParams: { response_type: 'code', audience: 'https://your-api-identifier', scope: 'openid profile email' }, // Custom routes routes: { login: '/auth/login', // Default: /login logout: '/auth/logout', // Default: /logout callback: '/auth/callback', // Default: /callback postLogoutRedirect: '/' // Where to go after logout }, // Session configuration session: { rol