Skip to main content

Authentication Overview

The Los Inmaduros Backend API uses Clerk for authentication and authorization. Authenticated endpoints require a valid JWT (JSON Web Token) issued by Clerk to be included in the request headers.

Authentication Method

The API uses Bearer Token authentication. When making authenticated requests, you must include an Authorization header with your JWT token:
Authorization: Bearer <your-jwt-token>

How It Works

  1. User Authentication: Users authenticate through Clerk on the frontend application
  2. Token Generation: Clerk generates a JWT token for the authenticated session
  3. Token Verification: The backend verifies the token using Clerk’s SDK
  4. User Synchronization: The backend automatically creates or retrieves the user record in the database
  5. Request Authorization: The authenticated user’s ID and role are attached to the request

Authorization Header Format

Include the JWT token in the Authorization header with the Bearer prefix:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Authenticated Request Example

Here’s a complete example of making an authenticated request using curl:
curl -X GET http://localhost:4000/api/favorites \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Creating a Review (POST Example)

curl -X POST http://localhost:4000/api/routes/123e4567-e89b-12d3-a456-426614174000/reviews \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "rating": 5,
    "comment": "Amazing route! Great for beginners."
  }'

Authentication Levels

The API implements three levels of authentication:

1. Public Endpoints (No Auth Required)

These endpoints are accessible without authentication:
  • GET /api/routes - Get all routes
  • GET /api/routes/:slug - Get route details
  • GET /api/route-calls - Get all route calls
  • GET /api/route-calls/:id - Get route call by ID
  • GET /api/photos - Get public photos
  • GET /api/routes/:slug/gallery - Get route gallery
  • GET /api/route-calls/:id/gallery - Get route call gallery

2. Authenticated Endpoints (Auth Required)

These endpoints require a valid JWT token: Reviews:
  • POST /api/routes/:routeId/reviews - Create review
  • GET /api/reviews/my-reviews - Get user’s reviews
  • PUT /api/reviews/:reviewId - Update review (owner only)
  • DELETE /api/reviews/:reviewId - Delete review (owner/admin only)
Favorites:
  • GET /api/favorites - Get user’s favorites
  • GET /api/favorites/check/:routeId - Check if route is favorited
  • POST /api/routes/:routeId/favorites - Add to favorites
  • DELETE /api/routes/:routeId/favorites/:favoriteId - Remove from favorites
Route Calls:
  • POST /api/route-calls - Create route call
  • PUT /api/route-calls/:id - Update route call (organizer only)
  • PATCH /api/route-calls/:id/cancel - Cancel route call (organizer/admin only)
  • DELETE /api/route-calls/:id - Delete route call (organizer/admin only)
Attendances:
  • GET /api/attendances/my-attendances - Get user’s attendances
  • POST /api/route-calls/:routeCallId/attendances - Confirm attendance
  • DELETE /api/route-calls/:routeCallId/attendances/:attendanceId - Cancel attendance
Photos:
  • POST /api/photos - Upload photo
  • GET /api/photos/my-photos - Get user’s photos
  • DELETE /api/photos/:id - Delete photo (owner/admin only)
  • PATCH /api/route-calls/:id/cover-photo - Update cover photo (organizer only)

3. Admin-Only Endpoints (Admin Role Required)

These endpoints require authentication AND the user must have the ADMIN role:
  • GET /api/photos/pending-review - Get photos pending moderation
  • PATCH /api/photos/:id/approve - Approve photo
  • PATCH /api/photos/:id/reject - Reject photo

Authentication Middleware

The backend uses three authentication middleware functions:

requireAuth

Requires a valid authentication token. Adds auth object to the request:
req.auth = {
  userId: string;      // Internal database user ID
  clerkId: string;     // Clerk user ID
  role: string;        // User role (USER or ADMIN)
}

requireAdmin

Must be used after requireAuth. Restricts access to users with ADMIN role.

optionalAuth

Adds auth to request if token is present, but doesn’t require it. Useful for endpoints that provide different data based on authentication status.

Error Responses

401 Unauthorized

Returned when authentication is required but no valid token is provided:
{
  "success": false,
  "error": "No authentication token provided"
}
Or when the token is invalid:
{
  "success": false,
  "error": "Invalid authentication token"
}

403 Forbidden

Returned when authenticated but lacking required permissions:
{
  "success": false,
  "error": "Admin access required"
}
Or when trying to modify resources owned by others:
{
  "success": false,
  "error": "Only the organizer can update this route call"
}

Development Test Token (Development Only)

This endpoint is only available in development mode and should never be used in production.
For testing purposes in development, you can generate a test JWT token:
POST http://localhost:4000/api/auth/test-token
Content-Type: application/json

{
  "email": "[email protected]"
}
Response:
{
  "success": true,
  "message": "Test token generated successfully",
  "data": {
    "userId": "user_2abc123def456",
    "email": "[email protected]",
    "sessionId": "sess_abc123",
    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "warning": "This endpoint should be removed in production",
    "instructions": "Copy this token and use it in Postman: Authorization: Bearer <token>"
  }
}
The user must already exist in Clerk before generating a test token. Create users through the Clerk dashboard first.

Security Best Practices

  1. Never share tokens: Keep your JWT tokens secure and never commit them to version control
  2. Token expiration: Tokens expire automatically - implement token refresh in your frontend
  3. HTTPS in production: Always use HTTPS in production to encrypt token transmission
  4. Secure storage: Store tokens securely in your frontend (httpOnly cookies or secure storage)
  5. Remove test endpoint: Ensure the /api/auth/test-token endpoint is disabled in production

Integration Example

Here’s a complete example of integrating authentication in a JavaScript/TypeScript frontend:
// Example: Fetch user's favorites with authentication
async function getUserFavorites(clerkToken: string) {
  const response = await fetch('http://localhost:4000/api/favorites', {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${clerkToken}`
    }
  });

  const data = await response.json();
  
  if (!data.success) {
    console.error('Error:', data.error);
    return null;
  }
  
  return data.data;
}

// Example: Create a route call
async function createRouteCall(clerkToken: string, routeCallData: any) {
  const response = await fetch('http://localhost:4000/api/route-calls', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${clerkToken}`
    },
    body: JSON.stringify(routeCallData)
  });

  const data = await response.json();
  
  if (!data.success) {
    console.error('Error:', data.error);
    return null;
  }
  
  return data.data;
}

Clerk Configuration

The backend requires the following Clerk environment variable to be configured:
CLERK_SECRET_KEY=your_clerk_secret_key
Ensure this is properly set in your .env file for the authentication to work correctly.

Build docs developers (and LLMs) love