Protect Your Express.js API with JWT Authentication
This guide demonstrates how to add JWT authentication to your Express.js API using theexpress-oauth2-jwt-bearer SDK. You’ll validate access tokens issued by Auth0, protect API routes, and implement scope-based authorization.
Prerequisites: Before you begin, ensure you have:
- Node.js 18 LTS or newer (supports
^18.12.0 || ^20.2.0 || ^22.1.0 || ^24.0.0)- npm 8+ (or yarn/pnpm)
- An Auth0 account (free tier available)
- Basic familiarity with Express.js
Get Started
1. Create a new Express project
Create a new directory and initialize a Node.js project:2. Install dependencies
Install Express, the authentication SDK, and dotenv for environment variable management:3. Configure your Auth0 API
You need an Auth0 API to issue access tokens for your Express application. Configure Auth0 using the CLI or manually via the Dashboard:- Tab Title
- Tab Title
If you have the Auth0 CLI installed, run:After creation, note the Identifier value—this is your
AUTH0_AUDIENCE.4. Create environment configuration
Create a.env file in your project root with your Auth0 configuration:
ℹ️ Finding your Auth0 Domain: In the Auth0 Dashboard, your domain appears in the top-left corner or under Settings → General. It typically looks like dev-abc123.us.auth0.com.
| Variable | Description | Example |
|---|---|---|
AUTH0_DOMAIN | Your Auth0 tenant domain | dev-abc123.us.auth0.com |
AUTH0_AUDIENCE | The API Identifier you created | https://api.example.com |
5. Create the server
Createserver.js (or server.ts for TypeScript) with the following code:
6. Run your API
Start the server:ℹ️ Your API is now running at http://localhost:3000.
✅ Checkpoint: Verify your API is protecting routes correctly: Test the public endpoint (should return 200):Test the private endpoint without a token (should return 401):You should receive:
- Public endpoint:
{"message":"Hello from a public endpoint!..."}- Private endpoint:
{"error":"unauthorized","message":"Authentication required"}
7. Test with a valid token
To test the protected endpoint with a valid access token:- Go to Auth0 Dashboard → Applications → APIs
- Select your API → Test tab
- Copy the generated access token
✅ Success! Your Express API is now protected with JWT authentication.
Add Scope-Based Authorization
Scopes allow fine-grained access control. You can require specific scopes for different endpoints.1. Configure scopes in Auth0
- In the Auth0 Dashboard, go to Applications → APIs → Your API
- Navigate to the Permissions tab
- Add the following scopes:
read:messages- Read messageswrite:messages- Write messagesadmin:access- Administrative access
2. Protect routes with scopes
Update your server to use scope-based authorization:3. Request tokens with scopes
When obtaining tokens, include the required scopes in the authorization request. The scopes granted will be included in the token’sscope claim.
⚠️ Important: If a request lacks the required scope, the API returns403 Forbiddenwith aninsufficient_scopeerror.
Add Claim Validation
Beyond scopes, you can validate custom claims in the JWT payload.Validate specific claim values
Troubleshooting
Advanced Usage
Complete Example
Here’s a complete Express API with all features:Next Steps
Now that your Express API is protected with JWT authentication, you can:- Add more protected routes with different scope requirements
- Implement refresh token rotation for long-lived sessions
- Add rate limiting to protect against abuse
- Connect a frontend application that obtains tokens from Auth0
- Enable DPoP for enhanced token security (proof-of-possession)
Useful Resources
- express-oauth2-jwt-bearer README
- Auth0 API Documentation
- JWT.io - Debug and decode JWTs
- OAuth 2.0 RFC 6750 - Bearer Token Usage
✅ Congratulations! You’ve successfully protected your Express.js API with JWT authentication using Auth0 and express-oauth2-jwt-bearer.