Skip to main content
The Cat Data API uses Auth0 for authentication and authorization. All protected endpoints require a valid JWT token issued by Auth0.

Authentication Flow

1

User Authenticates with Auth0

Users authenticate through Auth0’s authentication flow (hosted login, social login, etc.).
2

Auth0 Issues JWT Token

Upon successful authentication, Auth0 issues a JWT token signed with RS256 algorithm.
3

Client Sends Token

The client includes the JWT token in the Authorization header: Bearer {token}
4

API Verifies Token

The checkJwt middleware validates the token using Auth0’s public keys from the JWKS endpoint.

JWT Middleware Implementation

The checkJwt middleware is implemented using express-jwt and jwks-rsa:
src/middlewares/checkJwt.ts
import { expressjwt } from 'express-jwt';
import jwksRsa from 'jwks-rsa';
import { RequestHandler } from 'express';
import dotenv from 'dotenv';
dotenv.config();

const domain = process.env.AUTH0_DOMAIN; 
const audience = process.env.AUTH0_AUDIENCE; 
console.log('issuer:', domain);
export const checkJwt: RequestHandler = expressjwt({
    secret: jwksRsa.expressJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: `${domain}.well-known/jwks.json`,
    }),
    audience: audience,
    issuer: `${domain}`,
    algorithms: ['RS256'],
});

Configuration Parameters

jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `${domain}.well-known/jwks.json`,
})

JWKS Configuration

  • cache: true - Caches the signing keys to reduce requests to Auth0
  • rateLimit: true - Enables rate limiting for JWKS requests
  • jwksRequestsPerMinute: 5 - Limits JWKS endpoint requests to 5 per minute
  • jwksUri - The Auth0 JWKS endpoint URL for fetching public keys
The JWKS (JSON Web Key Set) endpoint provides the public keys used to verify JWT signatures. Caching these keys improves performance and reduces load on Auth0’s servers.

JWT Validation Parameters

  • secret - The JWKS client that fetches and caches Auth0’s public keys
  • audience - The API identifier configured in Auth0 (must match token’s aud claim)
  • issuer - Your Auth0 domain (must match token’s iss claim)
  • algorithms - Only RS256 algorithm is accepted for token verification
The audience parameter is critical for security. It ensures tokens issued for other APIs cannot be used with your API.

Environment Variables

The following environment variables must be configured:
.env
AUTH0_DOMAIN=https://your-tenant.auth0.com/
AUTH0_AUDIENCE=https://your-api-identifier
The AUTH0_DOMAIN should include the trailing slash and the https:// protocol.

Getting Your Auth0 Configuration

1

Create an API in Auth0

Go to the Auth0 Dashboard → Applications → APIs and create a new API. The identifier you choose will be your AUTH0_AUDIENCE.
2

Note Your Domain

Your Auth0 domain is shown in the dashboard (e.g., https://dev-abc123.us.auth0.com/).
3

Configure Environment Variables

Add both values to your .env file.

Protected Endpoints

The checkJwt middleware is applied to all image-related endpoints:
src/index.ts
app.post('/api/upload', checkJwt, upload.single('file'), async (req, res) => {
  // Upload handler
});

app.delete('/api/image/:id', checkJwt, async (req, res) => {
  // Delete handler
});

app.get('/api/image/:id', checkJwt, async (req, res) => {
  // Get handler
});

app.get('/api/images', checkJwt, async (req, res) => {
  // List handler
});
The middleware is placed before the route handlers, ensuring authentication happens before any business logic executes.

Authentication Error Responses

When authentication fails, the middleware automatically returns appropriate error responses:

Missing Token

Status: 401 Unauthorized
{
  "error": "UnauthorizedError",
  "message": "No authorization token was found"
}

Invalid Token

Status: 401 Unauthorized
{
  "error": "UnauthorizedError",
  "message": "invalid token"
}

Expired Token

Status: 401 Unauthorized
{
  "error": "UnauthorizedError",
  "message": "jwt expired"
}

Wrong Audience

Status: 401 Unauthorized
{
  "error": "UnauthorizedError",
  "message": "jwt audience invalid"
}

Dependencies

The Auth0 integration requires two npm packages:
package.json
{
  "dependencies": {
    "express-jwt": "^8.x",
    "jwks-rsa": "^3.x"
  }
}
  • express-jwt - Express middleware for validating JWTs
  • jwks-rsa - Library for retrieving RSA signing keys from JWKS endpoints
RS256 (RSA Signature with SHA-256) is an asymmetric algorithm that uses a public/private key pair. Auth0 signs tokens with a private key, and the API verifies them using the public key fetched from the JWKS endpoint. This means the API never needs access to the signing key, making it more secure than symmetric algorithms like HS256.

CORS Configuration

The API is configured to accept requests from the frontend application:
src/index.ts
app.use(cors({
  origin: 'http://localhost:5173',
  credentials: true,
}));
In production, update the CORS origin to match your deployed frontend URL. Never use origin: '*' with credentials: true.