Skip to main content

Overview

The DonaSF API uses JSON Web Tokens (JWT) for authentication. This guide covers how to obtain, use, and manage authentication tokens in your applications.

Authentication Flow

1

Register or Login

Create a new client account or authenticate with existing credentials
2

Receive JWT Token

The API returns a JWT token with user information and expiration time
3

Include Token in Requests

Add the token to the Authorization header for protected endpoints
4

Token Expiration

Tokens expire after 7 days and must be refreshed by logging in again

JWT Configuration

The API uses the following JWT configuration from appsettings.json:
{
  "Jwt": {
    "Key": "Q1w2e3r4t5y6u7i8o9p0a1s2d3f4g5h6j7k8l90@",
    "Expires": 3600
  }
}
Jwt.Key
string
required
The secret key used to sign and verify JWT tokens. This should be kept secure and never exposed in client applications.
Jwt.Expires
integer
Token expiration time in seconds. Note that the actual token creation uses a 7-day expiration period.

Token Validation

The API validates tokens using the following parameters configured in Program.cs:
options.TokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuer = false,
    ValidateAudience = false,
    ValidateLifetime = true,
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = new SymmetricSecurityKey(
        Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])
    )
};
Security Notice: The API currently does not validate issuer or audience claims. Only token lifetime and signature are validated.

Obtaining a Token

Standard Login

Use email or phone as the identifier to authenticate:
curl -X POST http://localhost:5005/Cliente/Login \
  -H "Content-Type: application/json" \
  -d '{
    "Identificador": "[email protected]",
    "Password": "yourpassword123"
  }'

OAuth/Identity Provider Login

For third-party authentication providers:
POST /Cliente/LoginID
Content-Type: application/json

{
  "IdProvider": "google-oauth2|123456789",
  "CorreoElectronico": "[email protected]"
}

Token Response Structure

The Token object returned from authentication endpoints:
public class Token
{
    public string Tokens { get; set; }           // The JWT string
    public string Identificador { get; set; }    // Email or phone number
    public DateTime Expiracion { get; set; }     // Token expiration date
    public int IdCliente { get; set; }           // Client ID
    public string Nombre { get; set; }           // Client name
    public bool Activo { get; set; }             // Account active status
}
Example Response:
{
  "Tokens": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZENsaWVudGUiOiIxMjMiLCJJZGVudGlmaWNhZG9yIjoiam9obi5kb2VAZXhhbXBsZS5jb20iLCJjb3JyZW8iOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsInRlbGVmb25vIjoiNTU1MTIzNDU2NyIsIm5vbWJyZSI6IkpvaG4gRG9lIiwiQ29udHJhc2VuYSI6InlvdXJwYXNzd29yZDEyMyIsImV4cCI6MTcxMDY4MTYwMH0.signature",
  "Identificador": "[email protected]",
  "Expiracion": "2026-03-13T12:00:00Z",
  "IdCliente": 123,
  "Nombre": "John Doe",
  "Activo": true
}
Tokens
string
required
The JWT token string to use in the Authorization header
Identificador
string
required
The email or phone number used to authenticate
Expiracion
DateTime
required
UTC timestamp when the token expires (7 days from creation)
IdCliente
integer
required
Unique client identifier
Nombre
string
required
Client’s full name
Activo
boolean
required
Whether the client account is active

JWT Claims

The token includes the following claims:
var claims = new List<Claim>()
{
    new Claim("IdCliente", idCliente.ToString()),
    new Claim("Identificador", identificador),
    new Claim("correo", correo),
    new Claim("telefono", telefono),
    new Claim("nombre", nombre),
    new Claim("Contrasena", contrasena)
};
Security Warning: The current implementation includes the password in the token claims. This is a security risk and should be removed in production environments.

Using the Token

Authorization Header

Include the JWT token in the Authorization header using the Bearer scheme:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Implementation Examples

var client = new HttpClient();

// Set the Authorization header with the Bearer token
client.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", token.Tokens);

// Make authenticated requests
var response = await client.GetAsync("http://localhost:5005/Donacion/VerDonaciones");

Token Expiration

Expiration Time

Tokens expire 7 days after creation:
var ahora = DateTime.UtcNow;
var expiracion = ahora.AddDays(7);

var securityToken = new JwtSecurityToken(
    claims: claims,
    expires: expiracion,
    signingCredentials: creds
);

Checking Expiration

The Expiracion field in the token response indicates when the token will expire. Monitor this field and refresh the token before expiration.
const token = {
  "Tokens": "eyJhbGci...",
  "Expiracion": "2026-03-13T12:00:00Z"
};

const expirationDate = new Date(token.Expiracion);
const now = new Date();
const isExpired = now > expirationDate;

if (isExpired) {
  // Re-authenticate to get a new token
  console.log('Token expired, please login again');
}

Token Refresh

The API does not currently support token refresh. When a token expires, you must re-authenticate using the /Cliente/Login endpoint to obtain a new token.
Best Practice: Implement automatic token refresh in your application by checking expiration time and logging in again before the token expires.

Error Responses

Invalid Credentials

{
  "status": 400,
  "message": "Usuario o contraseña incorrectos"
}

Expired Token

When using an expired token, the API will return a 401 Unauthorized response:
{
  "status": 401,
  "message": "Unauthorized"
}

Missing Authorization Header

{
  "status": 401,
  "message": "Unauthorized"
}

Security Best Practices

Secure Storage

Store tokens securely using platform-specific secure storage (KeyChain, KeyStore, encrypted storage)

HTTPS Only

Always use HTTPS in production to prevent token interception

Token Expiration

Implement automatic token refresh before expiration

Logout Cleanup

Clear stored tokens when users log out

Complete Authentication Example

Here’s a complete example of authentication flow with token management:
public class AuthService
{
    private readonly HttpClient _client;
    private Token _currentToken;

    public AuthService()
    {
        _client = new HttpClient { BaseAddress = new Uri("http://localhost:5005") };
    }

    public async Task<bool> LoginAsync(string identifier, string password)
    {
        var loginRequest = new JSONPass
        {
            Identificador = identifier,
            Password = password
        };

        var content = new StringContent(
            JsonSerializer.Serialize(loginRequest),
            Encoding.UTF8,
            "application/json"
        );

        var response = await _client.PostAsync("/Cliente/Login", content);

        if (response.IsSuccessStatusCode)
        {
            _currentToken = await response.Content.ReadFromJsonAsync<Token>();
            _client.DefaultRequestHeaders.Authorization = 
                new AuthenticationHeaderValue("Bearer", _currentToken.Tokens);
            return true;
        }

        return false;
    }

    public bool IsTokenExpired()
    {
        if (_currentToken == null) return true;
        return DateTime.UtcNow >= _currentToken.Expiracion;
    }

    public async Task<HttpResponseMessage> MakeAuthenticatedRequestAsync(
        string endpoint, 
        HttpContent content = null)
    {
        if (IsTokenExpired())
        {
            throw new UnauthorizedAccessException("Token expired, please login again");
        }

        return await _client.PostAsync(endpoint, content);
    }
}

Next Steps

Quick Start

Learn how to make your first authenticated API calls

API Reference

Explore all available endpoints

Error Handling

Handle authentication errors properly

Architecture

Understand the system architecture

Configuration

Configure JWT settings

Deployment

Deploy your API to production

Build docs developers (and LLMs) love