> ## Documentation Index
> Fetch the complete documentation index at: https://docs.backant.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Protecting routes with Bearer token authentication in BackAnt.

BackAnt ships a `token_required` decorator in `api/decorators/token_required.py` that validates the `Authorization: Bearer <token>` header on incoming requests.

## The `token_required` decorator

```python theme={null}
from functools import wraps
from flask import request
from helper.execution_tracking.Logger import myLogger as logger
from helper.execution_tracking.APIException import APIException

def token_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        auth_header = request.headers.get("Authorization", None)
        if not auth_header:
            raise APIException(status_code=401)

        token = auth_header.split()[1]
        if not token:
            raise APIException(status_code=401)

        try:
            # Validate token here (e.g. decode JWT, check Cognito)
            ...
        except Exception as e:
            raise APIException(status_code=401)

        return f(*args, **kwargs)
    return decorated_function
```

## Protecting a route

Apply `@token_required` as a decorator on the route function:

```python theme={null}
from decorators.token_required import token_required

@users_bp.get("")
@token_required
def get_users():
    response = myUsersService.get_users()
    return jsonify(response)
```

Requests without a valid `Authorization` header return:

```json theme={null}
HTTP 401
{"message": "Ocurrió un error"}
```

## JWT validation

The default decorator has a placeholder for token validation. To validate JWTs, add your decoding logic in the `try` block:

```python theme={null}
import jwt

def token_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        auth_header = request.headers.get("Authorization", None)
        if not auth_header:
            raise APIException(status_code=401)

        token = auth_header.split()[1]
        try:
            decoded_token = jwt.decode(token, options={"verify_signature": False})
            logger.debug(f"Decoded: {decoded_token}")
        except Exception as e:
            logger.debug(f"Exception: {e}")
            raise APIException(status_code=401)

        return f(*args, **kwargs)
    return decorated_function
```

## AWS Cognito authentication

The `Environment` class includes all necessary Cognito variables for validating Cognito JWTs:

```python theme={null}
COGNITO_REGION = os.getenv("COGNITO_REGION")
COGNITO_USERPOOL_ID = os.getenv("COGNITO_USERPOOL_ID")
COGNITO_APP_CLIENT_ID = os.getenv("COGNITO_APP_CLIENT_ID")
```

Use the `flask-Cognito` package (included in `requirements.txt`) to validate Cognito tokens inside `token_required`.

## Making authenticated requests

```bash theme={null}
curl http://localhost:5000/users \
  -H "Authorization: Bearer <your_token>"
```
