AWS sam: test en local ApiGateway Lambda authorizer

AWS sam: test en local ApiGateway Lambda authorizer

Probando lambda ApiGateway lambda Authorizer en local

En post anteriores comentaba las posibilidades que ofrece AWS sam para probar localmente nuestras Apis Con Dynamo DB y Generando Logs Localmente.

En la última actualización de AWS sam, se agregó una funcionalidad muy util que es la posibilidad de probar localmente los Authorizer que se tengan configurados en el ApiGateway.

En este repositorio de GitHub https://github.com/olcortesb/sam-api-authorizer he dejado una demo completa de como probar los Authorizer localmente.

A continuación dejo algunos detalles adicionales

Actualizar la versión de AWS sam:

La versión a partir de la cual esta funcionalidad está disponible es la 1.80.0

Para verificar la versión que tenemos instalada y actualizar:

sam --version
# SAM CLI, version 1.76.0

# For mac
brew upgrade aws-sam-cli

sam --version
# SAM CLI, version 1.81.0

Como actualizar AWS sam Para distintos sistemas operativos: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html

Código e infraestructura

Deentro del proyecto se encontraran tre archivos que son los principales:

  • template.yaml -> Definicion de la infrastructura (Api y lambdas)

  • authorizer.js -> La lambda que contiene el Custom authorizer

  • handler.js -> la lambda que esta detras del Api Gateway y el Authorizer.

Definiendo el Authorizer dentro de la API

# File template.yaml
Resources:
  LoggerApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: dev
      Auth:
        DefaultAuthorizer: JWTCustomAuthorizer
        Authorizers: # Definitions of authorizer
          JWTCustomAuthorizer:
            FunctionPayloadType: TOKEN
            FunctionArn: !GetAtt JWTAuthFunction.Arn

Definiendo la lambda que se ejecutara para validar el Authorizer tipo TOKEN

# File template.yaml
  JWTAuthFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: authorizer.lambdaHandler
      Runtime: nodejs18.x
      CodeUri: .
      Architectures:
        - x86_64

Código de lambda basado en el template que provee aws: LInk

⚠️ No usar en producción, remplazar por la validación del JWT correspondiente.

// File authorizer.js
const validate_token_and_user = async (token)=>{
    // Validate token Demo
    // No use in productions...
    // valide your token here
    console.log("Log from lambda authorizer ...");
    console.log("The token: ",token);
    if (token.split(' ').pop() === 'e81a50b9'){
        return true;
    }
    return false;
}

Levantar el proyecto en local

Descargar el proyecto del repositorio: https://github.com/olcortesb/sam-api-authorizer

Ahora levantamos las apis

sam local start-api -p 3002 --log-file logfile.txt

Llamamos al endpoint /logger

Probamos pasando el token errado ...

curl -X GET \
  'http://127.0.0.1:3002/logger' \
  --header 'Accept: */*' \
  --header 'Authorization: Bearer e81a50b9ddd'
# Response:
# { 
#  "message": "User is not authorized to access this resource"
# }

Y pasando el token correcto

curl -X GET \
  'http://127.0.0.1:3002/logger' \
  --header 'Accept: */*' \
  --header 'Authorization: Bearer e81a50b9'

# Response
# "OK"

Finalmente, utilizando la funcionalidad de generar un log localmente como si fuera AWS CloudWatch (Link), podemos ver los logs que hemos dejado dentro de la lambda Authorizer.

START RequestId: c0bd0c4a-0722-4b82-8c68-d56c0b26d128 Version: $LATEST
2023-04-24T13:05:22.621Z    c0bd0c4a-0722-4b82-8c68-d56c0b26d128    INFO    Method ARN: arn:aws:execute-api:us-east-1:123456789012:1234567890/dev/GET/logger
2023-04-24T13:05:22.627Z    c0bd0c4a-0722-4b82-8c68-d56c0b26d128    INFO    Token fron event: Bearer e81a50b9
2023-04-24T13:05:22.628Z    c0bd0c4a-0722-4b82-8c68-d56c0b26d128    INFO    Log from lambda authorizer ...
2023-04-24T13:05:22.628Z    c0bd0c4a-0722-4b82-8c68-d56c0b26d128    INFO    El token:  Bearer e81a50b9
END RequestId: c0bd0c4a-0722-4b82-8c68-d56c0b26d128
REPORT RequestId: c0bd0c4a-0722-4b82-8c68-d56c0b26d128    Init Duration: 1.69 ms    Duration: 1523.58 ms    Billed Duration: 1524 ms    Memory Size: 128 MB    Max Memory Used: 128 MB

¡Eso es todo por ahora, espero sea útil, gracias!

Saludos

Referencias