> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Yurben-bit/Sistema-de-Administraci-n-Escolar-Backend/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> JWT-based authentication system implementation in EduTec Backend

## Overview

EduTec Backend implements a **stateless authentication system** using JSON Web Tokens (JWT). This approach eliminates the need for server-side session storage, making the API scalable and suitable for distributed environments.

<Info>
  The application uses **jjwt library version 0.11.5** for JWT operations, providing modern cryptographic standards and comprehensive token management.
</Info>

## Authentication Flow

The authentication process follows these steps:

```
┌──────────┐                  ┌──────────────┐                  ┌────────────┐
│  Client  │                  │ AuthController│                  │ JwtService │
└─────┬────┘                  └──────┬───────┘                  └─────┬──────┘
      │                              │                                 │
      │  POST /auth/login            │                                 │
      │  {username, password}        │                                 │
      ├─────────────────────────────>│                                 │
      │                              │                                 │
      │                              │  generateToken(username)        │
      │                              ├────────────────────────────────>│
      │                              │                                 │
      │                              │         JWT Token               │
      │                              │<────────────────────────────────┤
      │                              │                                 │
      │         JWT Token            │                                 │
      │<─────────────────────────────┤                                 │
      │                              │                                 │
```

1. Client sends credentials to `/auth/login`
2. Controller receives and extracts the `LoginRequest` DTO
3. Controller delegates token generation to `JwtService`
4. Service creates a signed JWT with username and expiration
5. Token is returned to the client as a plain string
6. Client includes token in subsequent requests via `Authorization` header

<Warning>
  The current implementation does **not validate credentials** against the database. The login endpoint generates tokens for any username without password verification. This should be enhanced with proper authentication logic before production deployment.
</Warning>

## JWT Service Implementation

The `JwtService` class handles all token operations using the JJWT library.

### Service Configuration

```java theme={null}
// src/main/java/com/tecmilenio/edutec/security/JwtService.java:1-13
package com.tecmilenio.edutec.security;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.security.Key;

@Service
public class JwtService {
    // Clave de al menos 32 caracteres
    private static final String SECRET_KEY = "12345678910111213141516171819200";
    // pre-generando la llave criptográfica solo cuando inicia la aplicación
    private static final Key KEY = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
```

<Tabs>
  <Tab title="@Service Annotation">
    Marks this class as a Spring-managed service component, making it available for dependency injection throughout the application.
  </Tab>

  <Tab title="SECRET_KEY">
    A 33-character secret key used for signing tokens. This key ensures token integrity and prevents tampering.

    <Warning>
      **Security Risk:** The secret key is hardcoded. In production environments, this should be externalized to environment variables or secure configuration management systems (e.g., AWS Secrets Manager, HashiCorp Vault).
    </Warning>
  </Tab>

  <Tab title="KEY">
    A pre-computed cryptographic `Key` object generated using HMAC-SHA algorithm. Computing this once at class initialization improves performance by avoiding repeated key generation.
  </Tab>
</Tabs>

### Token Generation

The `generateToken()` method creates a signed JWT containing the username and expiration time:

```java theme={null}
// src/main/java/com/tecmilenio/edutec/security/JwtService.java:19-27
public String generateToken(String username) {
    return Jwts.builder()
            .setSubject(username)
            .setIssuedAt(new Date(System.currentTimeMillis()))
            .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
            // Fíjate en el orden: primero la llave, luego el algoritmo
            .signWith(KEY, SignatureAlgorithm.HS256)
            .compact();
}
```

#### Token Claims

<Accordion title="Subject (sub)">
  **Value:** Username provided during login

  **Purpose:** Identifies the user this token belongs to

  ```java theme={null}
  .setSubject(username)
  ```

  The subject is the primary identifier stored in the token. Subsequent requests can extract this to determine which user is making the request.
</Accordion>

<Accordion title="Issued At (iat)">
  **Value:** Current timestamp in milliseconds

  **Purpose:** Records when the token was created

  ```java theme={null}
  .setIssuedAt(new Date(System.currentTimeMillis()))
  ```

  Useful for auditing, token refresh logic, and debugging authentication issues.
</Accordion>

<Accordion title="Expiration (exp)">
  **Value:** Current time + 10 hours (36,000,000 milliseconds)

  **Purpose:** Defines token validity period

  ```java theme={null}
  .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
  ```

  Calculation breakdown:

  * `1000` ms = 1 second
  * `* 60` = 1 minute
  * `* 60` = 1 hour
  * `* 10` = **10 hours**

  <Info>
    Tokens automatically become invalid after 10 hours, requiring users to re-authenticate. This balance between convenience and security can be adjusted based on your requirements.
  </Info>
</Accordion>

<Accordion title="Signature">
  **Algorithm:** HMAC-SHA256 (HS256)

  **Key:** Pre-computed `KEY` from the secret

  ```java theme={null}
  .signWith(KEY, SignatureAlgorithm.HS256)
  ```

  The signature ensures:

  * **Integrity:** Token data hasn't been modified
  * **Authenticity:** Token was issued by this server
  * **Non-repudiation:** Only holders of the secret key can create valid tokens

  <Note>
    HMAC-SHA256 is a symmetric algorithm, meaning the same key signs and verifies tokens. For asymmetric scenarios (microservices, distributed systems), consider RSA or ECDSA algorithms.
  </Note>
</Accordion>

### Token Format

Generated tokens follow the standard JWT format:

```
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNzA5MjQwMDAwLCJleHAiOjE3MDkyNzYwMDB9.signature
│─────── Header ──────│──────────────────── Payload ────────────────────────│─ Signature ─│
```

* **Header:** Algorithm and token type (Base64 encoded)
* **Payload:** Claims including subject, issued at, expiration (Base64 encoded)
* **Signature:** HMAC-SHA256 signature to verify integrity

You can decode tokens at [jwt.io](https://jwt.io) for debugging (never share tokens containing sensitive data).

## Auth Controller

The `AuthController` provides the public API endpoint for authentication.

### Login Endpoint

```java theme={null}
// src/main/java/com/tecmilenio/edutec/controller/AuthController.java:1-21
package com.tecmilenio.edutec.controller;

import com.tecmilenio.edutec.dto.LoginRequest;
import com.tecmilenio.edutec.security.JwtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private JwtService jwtService;

    @PostMapping("/login")
    public String login(@RequestBody LoginRequest loginRequest) {
        System.out.println("El usuario " + loginRequest.getUsername() + " está intentando entrar");
        return jwtService.generateToken(loginRequest.getUsername());
    }
}
```

**Endpoint:** `POST /auth/login`

**Request Body:**

```json theme={null}
{
  "username": "string",
  "password": "string"
}
```

**Response:** Plain text JWT string

```
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNzA5MjQwMDAwLCJleHAiOjE3MDkyNzYwMDB9.KqJ8z9X...
```

**Status Code:** `200 OK`

<Note>
  The controller currently logs authentication attempts to the console. Consider using a proper logging framework (SLF4J/Logback) for production applications.
</Note>

## Login Request DTO

The `LoginRequest` class structures incoming authentication requests:

```java theme={null}
// src/main/java/com/tecmilenio/edutec/dto/LoginRequest.java:1-31
package com.tecmilenio.edutec.dto;

public class LoginRequest {
    private String username;
    private String password;

    public LoginRequest() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
```

**Fields:**

* `username` - User's unique identifier
* `password` - User's password (currently not validated)

**Design Pattern:** Plain Old Java Object (POJO) with getter/setter methods

<Info>
  Spring automatically deserializes JSON request bodies into this DTO using Jackson. The empty constructor is required for this process.
</Info>

## Security Best Practices

### Current Implementation Gaps

<Warning>
  The following security measures are **missing** from the current implementation:

  1. **Password Verification**: Credentials are not validated against the database
  2. **Password Hashing**: No BCrypt or similar hashing for stored passwords
  3. **Token Validation**: No middleware to verify tokens on protected endpoints
  4. **Secret Management**: Hardcoded secret key in source code
  5. **HTTPS Enforcement**: No SSL/TLS configuration specified
  6. **Rate Limiting**: No protection against brute force attacks
  7. **Input Validation**: No checks for empty/null username or password
</Warning>

### Recommended Enhancements

<Accordion title="1. Implement Password Verification">
  Add a `UserService` to authenticate credentials:

  ```java theme={null}
  @Service
  public class AuthService {
      @Autowired
      private UserRepository userRepository;
      
      @Autowired
      private PasswordEncoder passwordEncoder;
      
      public boolean authenticate(String username, String password) {
          User user = userRepository.findByUsername(username)
              .orElseThrow(() -> new UnauthorizedException("Invalid credentials"));
          
          return passwordEncoder.matches(password, user.getPassword());
      }
  }
  ```
</Accordion>

<Accordion title="2. Add Token Validation Filter">
  Create a filter to verify JWTs on protected endpoints:

  ```java theme={null}
  @Component
  public class JwtAuthenticationFilter extends OncePerRequestFilter {
      @Autowired
      private JwtService jwtService;
      
      @Override
      protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) {
          String token = extractToken(request);
          if (token != null && jwtService.validateToken(token)) {
              String username = jwtService.extractUsername(token);
              // Set authentication in SecurityContext
          }
          filterChain.doFilter(request, response);
      }
  }
  ```

  Add validation methods to `JwtService`:

  ```java theme={null}
  public boolean validateToken(String token) {
      try {
          Jwts.parserBuilder()
              .setSigningKey(KEY)
              .build()
              .parseClaimsJws(token);
          return true;
      } catch (JwtException e) {
          return false;
      }
  }

  public String extractUsername(String token) {
      return Jwts.parserBuilder()
          .setSigningKey(KEY)
          .build()
          .parseClaimsJws(token)
          .getBody()
          .getSubject();
  }
  ```
</Accordion>

<Accordion title="3. Externalize Secret Key">
  Move the secret to `application.properties`:

  ```properties theme={null}
  jwt.secret=${JWT_SECRET:default-dev-secret-change-in-production}
  jwt.expiration=36000000
  ```

  Update `JwtService`:

  ```java theme={null}
  @Value("${jwt.secret}")
  private String secretKey;

  @Value("${jwt.expiration}")
  private long expirationTime;

  @PostConstruct
  public void init() {
      this.key = Keys.hmacShaKeyFor(secretKey.getBytes());
  }
  ```
</Accordion>

<Accordion title="4. Add Input Validation">
  Use Bean Validation annotations:

  ```java theme={null}
  public class LoginRequest {
      @NotBlank(message = "Username is required")
      @Size(min = 3, max = 50)
      private String username;
      
      @NotBlank(message = "Password is required")
      @Size(min = 8, message = "Password must be at least 8 characters")
      private String password;
  }
  ```

  Update controller:

  ```java theme={null}
  @PostMapping("/login")
  public String login(@Valid @RequestBody LoginRequest loginRequest) {
      // Validation happens automatically
  }
  ```
</Accordion>

<Accordion title="5. Use BCrypt for Passwords">
  Hash passwords before storing in the database:

  ```java theme={null}
  @Bean
  public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder(12);
  }
  ```

  Update `User` entity:

  ```java theme={null}
  @PrePersist
  @PreUpdate
  private void encryptPassword() {
      if (this.password != null && !this.password.startsWith("$2a$")) {
          this.password = passwordEncoder.encode(this.password);
      }
  }
  ```
</Accordion>

### Token Usage Example

Once implemented, clients should include tokens in the `Authorization` header:

```http theme={null}
GET /api/users/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huZG9lIi...
```

## Dependencies

The JWT implementation relies on these libraries from `pom.xml:109-125`:

```xml theme={null}
<!-- Dependencias JWT-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
```

* **jjwt-api**: Core JWT API and interfaces
* **jjwt-impl**: Implementation of JWT specification
* **jjwt-jackson**: JSON processing using Jackson library

<Note>
  Spring Security starter (`spring-boot-starter-security`) is commented out in the POM file, indicating a lightweight custom authentication approach without the full Spring Security framework.
</Note>

## Next Steps

* [Database](/database) - Learn about the User entity and data persistence
* [Architecture](/architecture) - Understand the overall system design
* [API Reference](/api/auth/login) - Explore all available endpoints
