Secure Your Node.js API with Auth0 Authentication
When building APIs with Node.js and Express, securing user authentication is a critical step. While manually generating JSON Web Tokens (JWTs) works for basic authentication, real-world applications require a more secure and scalable solution. This is where Auth0 comes in.
In this guide, we’ll walk through integrating Auth0 API authentication into your Node.js Express project, allowing you to authenticate users effortlessly and manage secure API access.
Setting Up Auth0
1. Creating an Auth0 Application
Start by logging into your Auth0 Dashboard and navigating to Applications. Click Create Application and:
- Name your app (e.g., Task Manager App).
- Select Regular Web Application (which uses the OAuth 2.0 authorization code flow).
- Skip selecting apps for now and proceed to Settings.
- Leave everything as is but note that we’ll later update the Allowed Callback URLs.
2. Creating an API in Auth0
Next, navigate to APIs in Auth0 and click Create API:
- Set Task Manager API as the name.
- Use
task-manager-api
as the API Identifier (this is the audience in the access token). - Keep JSON Web Token (JWT) as the token format and select RS256 as the signing algorithm for better security.
Auth0 provides a quick start guide for different platforms. We’ll follow their recommendation and use the express-oauth2-jwt-bearer
library to validate tokens.
🚀Boost your career with Full Stack Software Developer Certificate 👉
Getting an Access Token
In real applications, authentication is typically handled on the frontend (e.g., a React SPA). However, since we don’t have a frontend in this tutorial, we can use the Auth0 Authentication API Debugger extension to obtain an access token.
1. Installing and Configuring the Debugger
- Install the Auth0 Authentication API Debugger extension.
- Open it and select the Task Manager App created earlier.
- Copy the callback URL from the debugger.
- Go back to the Auth0 dashboard, paste it under Allowed Callback URLs, and save the changes.
2. Generating an Access Token
- In the debugger, navigate to OAuth2/OIDC.
- Enter the API audience (
task-manager-api
). - Toggle Use the Audience.
- Click OAuth2/OIDC login, authenticate with Google, and get a JWT access token.
Implementing Auth0 Authentication in Node.js
Now that we have an access token, let’s integrate Auth0 authentication into our Node.js app.
1. Installing Dependencies
Run the following command to install the authentication library:
npm install express-oauth2-jwt-bearer
2. Configuring Environment Variables
Create a .env
file and add the following:
ISSUER_BASE_URL=<Auth0 Domain> AUDIENCE=task-manager-api
Replace <Auth0 Domain>
with your actual Auth0 domain.
3. Setting Up Authentication Middleware
In authenticate-user.ts
, update the authentication logic using express-oauth2-jwt-bearer
:
import { auth } from 'express-oauth2-jwt-bearer'; import config from '../config'; const authenticateUser = auth({ audience: config.AUDIENCE, issuerBaseURL: config.ISSUER_BASE_URL, }); export default authenticateUser;
This middleware will automatically verify access tokens from Auth0.
4. Updating Error Handling
Modify error-handler.ts
to properly handle authentication errors:
import { UnauthorizedError } from 'express-oauth2-jwt-bearer'; const errorHandler = (err, req, res, next) => { if (err instanceof UnauthorizedError) { return res.status(err.statusCode).json({ error: err.message, code: err.code || 'ERR_AUTH' }); } next(err); };
Now, our API correctly handles authentication failures.
Testing the Authentication Flow
With everything set up, let’s test API authentication using the token we obtained earlier.
1. Start the API Server
npm run dev
2. Use the Access Token
Copy the token from the Auth0 Authentication API Debugger and add it to the Authorization header in your API requests. For example, using an HTTP client like Postman or an .http
file:
GET http://localhost:5000/tasks Authorization: Bearer <your_access_token>
If everything is set up correctly, the API should authenticate the request.
3. Seeding User Data
If no tasks are returned, it’s because the authenticated user doesn’t have any tasks in the database. To fix this:
- Copy the sub (subject) property from the decoded access token.
- Open
prisma/seed.ts
and use it as the user ID. - Run:
npm run db:seed
- Re-test the API request. Now, tasks should be returned.
4. Testing Token Expiry and Errors
To see the authentication middleware in action:
- Modify the token (e.g., change a letter at the end) and re-run the request.
- You should get a 401 Unauthorized error with
signature verification failed
.
Conclusion
By following this guide, you’ve successfully secured your Node.js API using Auth0 authentication. This setup ensures that only authorized users can access protected resources.