Skip to main content

Overview

Tambo360 uses JSON Web Tokens (JWT) for authentication. Tokens are stored in secure HTTP-only cookies and automatically included in requests by the browser.

Authentication Flow

  1. User registers or logs in with credentials
  2. Server validates credentials and generates a JWT token
  3. Token is stored in an HTTP-only cookie with a 24-hour expiration
  4. Cookie is automatically sent with subsequent requests
  5. Server validates the token on protected routes
HTTP-only cookies prevent XSS attacks by making tokens inaccessible to JavaScript. The browser automatically handles token storage and transmission.

Security Scheme

The API uses cookie-based authentication:

Token Structure

The JWT payload contains:
Token Payload
{
  "user": {
    "nombre": "Juan Perez",
    "correo": "[email protected]",
    "idUsuario": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "verificado": true,
    "fechaCreacion": "2024-03-15T10:30:00.000Z",
    "establecimientos": []
  },
  "iat": 1710500400,
  "exp": 1710586800
}

Registration

Create a new user account.

Endpoint

POST /api/auth/crear-cuenta

Request Body

nombre
string
required
Full name of the user (5-50 characters)
correo
string
required
Valid email address (5-50 characters)
contraseña
string
required
Password meeting security requirements:
  • Minimum 8 characters, maximum 50
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number
  • At least one special character (@$!%*?&)

Example Request

curl -X POST https://api.tambo360.com/api/auth/crear-cuenta \
  -H "Content-Type: application/json" \
  -d '{
    "nombre": "Juan Perez",
    "correo": "[email protected]",
    "contraseña": "!Password123"
  }'

Response

statusCode
integer
HTTP status code: 201 for success
message
string
Success message
data
object
User object containing:
data.idUsuario
string
Unique user identifier (UUID)
data.nombre
string
User’s full name
data.correo
string
User’s email address
data.verificado
boolean
Email verification status (initially false)
data.fechaCreacion
string
Account creation timestamp (ISO 8601)
201 Success Response
{
  "statusCode": 201,
  "message": "Usuario registrado exitosamente",
  "data": {
    "idUsuario": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "nombre": "Juan Perez",
    "correo": "[email protected]",
    "verificado": false,
    "fechaCreacion": "2024-03-15T10:30:00.000Z"
  },
  "success": true
}
400 Validation Error
{
  "statusCode": 400,
  "message": [
    "correo es obligatorio",
    "contraseña debe tener al menos 8 caracteres"
  ],
  "success": false
}

Login

Authenticate a user and receive a JWT token.

Endpoint

POST /api/auth/iniciar-sesion

Request Body

correo
string
required
User’s email address
contraseña
string
required
User’s password

Example Request

curl -X POST https://api.tambo360.com/api/auth/iniciar-sesion \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{
    "correo": "[email protected]",
    "contraseña": "!Password123"
  }'

Response

statusCode
integer
HTTP status code: 200 for success
message
string
Success message
data
object
Login data containing:
data.user
object
User information
data.token
string
JWT token (also set in HTTP-only cookie)
200 Success Response
{
  "statusCode": 200,
  "message": "Inicio de sesión exitoso",
  "data": {
    "user": {
      "nombre": "Juan Perez",
      "correo": "[email protected]",
      "idUsuario": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
      "verificado": true,
      "fechaCreacion": "2024-03-15T10:30:00.000Z",
      "establecimientos": []
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "success": true
}
The token is automatically stored in an HTTP-only cookie named token with:
  • httpOnly: true - Prevents JavaScript access
  • secure: true - HTTPS only (production)
  • sameSite: 'none' - Cross-site requests (production) or 'lax' (development)
  • maxAge: 86400000 - 24 hour expiration

Get Current User

Retrieve the authenticated user’s information.

Endpoint

GET /api/auth/me

Authentication

Must include the token cookie from login

Example Request

curl -X GET https://api.tambo360.com/api/auth/me \
  -b cookies.txt

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Usuario obtenido exitosamente",
  "data": {
    "idUsuario": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "nombre": "Juan Perez",
    "correo": "[email protected]",
    "verificado": true,
    "fechaCreacion": "2024-03-15T10:30:00.000Z"
  },
  "success": true
}
401 Unauthorized
{
  "statusCode": 401,
  "message": "No autenticado",
  "success": false
}

Logout

End the user’s session by clearing the authentication cookie.

Endpoint

POST /api/auth/logout

Authentication

Must include the token cookie

Example Request

curl -X POST https://api.tambo360.com/api/auth/logout \
  -b cookies.txt

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Sesión cerrada correctamente",
  "success": true
}

Email Verification

Verify a user’s email address using a verification token.

Endpoint

POST /api/auth/verificar-email

Request Body

token
string
required
Email verification token sent to the user’s email

Example Request

curl -X POST https://api.tambo360.com/api/auth/verificar-email \
  -H "Content-Type: application/json" \
  -d '{
    "token": "b28a6254dd3cadca4e7f2c236ee3a412575af5d19fe1e982f5760a072635bc6f"
  }'

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Email verificado exitosamente",
  "success": true
}
400 Invalid Token
{
  "statusCode": 400,
  "message": "Token de verificación inválido o expirado",
  "success": false
}

Resend Verification Email

Resend the email verification link to a user.

Endpoint

POST /api/auth/reenviar-verificacion

Request Body

correo
string
required
User’s email address

Example Request

curl -X POST https://api.tambo360.com/api/auth/reenviar-verificacion \
  -H "Content-Type: application/json" \
  -d '{
    "correo": "[email protected]"
  }'

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Correo de verificación reenviado exitosamente",
  "success": true
}

Password Reset Flow

The password reset process involves three steps:

Step 1: Request Password Reset

Request a password reset token to be sent via email.

Endpoint

POST /api/auth/contrasena-olvidada

Request Body

correo
string
required
User’s email address

Example Request

curl -X POST https://api.tambo360.com/api/auth/contrasena-olvidada \
  -H "Content-Type: application/json" \
  -d '{
    "correo": "[email protected]"
  }'

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Instrucciones para restablecer la contraseña enviadas al correo",
  "success": true
}

Step 2: Verify Reset Token

Verify that the password reset token is valid.

Endpoint

POST /api/auth/verificar-restablecer-contrasena

Request Body

token
string
required
Password reset token from email

Example Request

curl -X POST https://api.tambo360.com/api/auth/verificar-restablecer-contrasena \
  -H "Content-Type: application/json" \
  -d '{
    "token": "b28a6254dd3cadca4e7f2c236ee3a412575af5d19fe1e982f5760a072635bc6f"
  }'

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Token de restablecimiento válido",
  "success": true
}

Step 3: Reset Password

Reset the password using the verified token.

Endpoint

POST /api/auth/restablecer-contrasena

Request Body

token
string
required
Password reset token from email
nuevaContraseña
string
required
New password meeting security requirements (same as registration)

Example Request

curl -X POST https://api.tambo360.com/api/auth/restablecer-contrasena \
  -H "Content-Type: application/json" \
  -d '{
    "token": "b28a6254dd3cadca4e7f2c236ee3a412575af5d19fe1e982f5760a072635bc6f",
    "nuevaContraseña": "!NewPassword456"
  }'

Response

200 Success Response
{
  "statusCode": 200,
  "message": "Contraseña restablecida exitosamente",
  "success": true
}

Authentication Errors

Common authentication errors and their meanings:

401 Unauthorized

Occurs when:
  • No authentication token is provided
  • Token is invalid or malformed
  • Token has expired (after 24 hours)
Error Response
{
  "statusCode": 401,
  "message": "No autenticado",
  "success": false
}
Token Error Response
{
  "statusCode": 401,
  "message": "Token inválido o expirado",
  "success": false
}

400 Bad Request

Occurs when:
  • Missing required fields (email, password, etc.)
  • Invalid email format
  • Password doesn’t meet security requirements
  • Account already exists
Validation Error
{
  "statusCode": 400,
  "message": [
    "correo es obligatorio",
    "contraseña debe tener al menos 8 caracteres"
  ],
  "success": false
}

Protected Routes

Routes that require authentication will return 401 Unauthorized if the token is missing or invalid. Always check the response status and handle authentication errors appropriately.

Example: Handling Authentication

javascript
async function makeAuthenticatedRequest(url, options = {}) {
  const response = await fetch(url, {
    ...options,
    credentials: 'include' // Always include cookies
  });
  
  if (response.status === 401) {
    // Token expired or invalid - redirect to login
    window.location.href = '/login';
    return null;
  }
  
  return response.json();
}

// Usage
const userData = await makeAuthenticatedRequest('https://api.tambo360.com/api/auth/me');
if (userData) {
  console.log('Current user:', userData.data);
}

Token Refresh

The current implementation does not support token refresh. When a token expires after 24 hours, users must log in again. Consider implementing a refresh token mechanism for production applications.

Security Best Practices

1. Never Store Tokens in LocalStorage

HTTP-only cookies are automatically used and provide better security than localStorage:
Good Practice
// The browser automatically handles cookies
fetch('/api/auth/me', {
  credentials: 'include'
});

2. Use HTTPS in Production

Always use HTTPS in production to prevent token interception:
  • The secure flag is automatically set on cookies in production
  • Ensures encrypted communication

3. Handle Token Expiration

Implement proper error handling for expired tokens:
javascript
if (response.status === 401) {
  // Clear any local state
  localStorage.clear();
  
  // Redirect to login
  window.location.href = '/login';
}

4. Validate Input Client-Side

Reduce attack surface by validating before sending:
javascript
function validatePassword(password) {
  const minLength = password.length >= 8;
  const hasUpper = /[A-Z]/.test(password);
  const hasLower = /[a-z]/.test(password);
  const hasNumber = /\d/.test(password);
  const hasSpecial = /[@$!%*?&]/.test(password);
  
  return minLength && hasUpper && hasLower && hasNumber && hasSpecial;
}

Next Steps

API Overview

Learn about API structure and best practices

Establishments

Manage farm establishments (requires authentication)

Dashboard

Access analytics and metrics

Error Handling

Handle API errors effectively

Build docs developers (and LLMs) love