Diego  Elizondo

Diego Elizondo

1654286700

Servicio De inicio De Sesión Sin Servidor Con AWS DynamoDB Y Lambda

Es 2022, serverless ya no es un término elegante que usan los fanáticos de la tecnología. Cada vez más personas se dan cuenta de que es el camino a seguir para crear aplicaciones rápidas y altamente escalables.

En este artículo, nos centraremos en crear un sistema de inicio de sesión sin servidor desde cero con AWS, utilizando dos de sus servicios populares:

Si ya tiene mucha experiencia con estos dos, lo cual supongo que no porque ha leído el título, el siguiente tutorial puede no ser para usted. Antes de comenzar, necesitará una cuenta de AWS para este proyecto, puede registrarse para obtener una aquí . Echemos un vistazo al sistema que vamos a construir.

Como puede ver, crearemos un servicio de inicio de sesión básico que utiliza una puerta de enlace API para acceder a la lambda que se conectará a DynamoDB. Tendremos tres puntos finales en nuestros proyectos, el primero es para registrar un nuevo usuario y almacenar los detalles en la base de datos. El segundo sería para el inicio de sesión del usuario y la emisión de un token JWT para el usuario. Y el tercero es verificar que el token sea válido. Empecemos.

1. Creación de una tabla de DynamoDB

El primer paso que vamos a dar es crear una tabla de DynamoDB donde almacenaremos nuestros datos de usuario.

Como se mencionó anteriormente, DynamoDB es una base de datos NoSQL, los datos se almacenan y consultan principalmente mediante una clave principal , que será la clave de partición y, en algunos casos, una combinación de clave de partición y clave de ordenación.

DynamoDB utiliza el valor de la clave de partición como entrada para una función hash interna que decide la partición en la que se almacenarán sus datos. Puede leer más sobre las claves aquí , ya que sería demasiado para cubrir en este artículo.

Para crear una tabla, vaya a su consola de AWS y busque DynamoDB en el cuadro de búsqueda superior y selecciónelo en los resultados de búsqueda. Una vez que esté en el panel de DynamoDB, haga clic en la opción Crear tabla (1.1)

1.1

Esto lo llevará a una página donde se le pedirá que proporcione los detalles de la tabla, como el nombre de la tabla y las claves principales (1.2).

Vamos a nombrar nuestra tabla user-table por ahora y definir el nombre de usuario como nuestra clave de partición, que es lo que usaremos para buscar usuarios. Puede ver que la clave de clasificación es opcional, la dejaremos en blanco ya que no es necesaria para nuestra aplicación simple.

1.2

Puede dejar el resto de la configuración con los valores predeterminados y hacer clic en crear tabla al final de la página. Esto creará su tabla en unos momentos. Ahora que la base de datos está lista, pasemos al siguiente paso.

2. Creación del rol de IAM

Para crear un rol de IAM, busque IAM en el cuadro de búsqueda superior y una vez que esté en el tablero, vaya a Roles desde el panel izquierdo (2.1) para crear un nuevo rol y haga clic en crear el rol.

2.1

En el paso 1, puede seleccionar Lambda de los casos de uso comunes (2.2), ya que para eso usaremos nuestro rol y pasar al siguiente paso.

2.2

En el siguiente paso, debemos agregar permisos para nuestro rol. Para este proyecto, vamos a agregar dos permisos.

El primero es para Dynamo DB y el otro para CloudWatch. Para agregarlos, simplemente busque Dynamo DB en el cuadro de búsqueda y seleccione el permiso de acceso completo de DynamoDB de la lista (2.3).

2.3

A continuación, busque el acceso completo de CloudWatch y agréguelo también. Vamos a usar CloudWatch para ver los registros de nuestra función lambda.

En el siguiente paso, asigne un nombre al rol que estamos creando y haga clic en crear rol al final de la página.

Esto creará un rol de IAM que conectaremos a nuestro lambda, lo que le permitirá conectarse a DynamoDB y CloudWatch sin problemas. Ahora pasemos al siguiente paso.

 

3. Crea la lambda

Ahora vamos a crear la lambda que servirá como backend para nuestras API. Busque lambda en el cuadro de búsqueda superior y haga clic en crear función una vez que esté en el panel de control de lambda.

En el siguiente paso, asigne un nombre al servicio lambda y deje el tiempo de ejecución predeterminado como Node.js, ya que eso es lo que usaremos para este proyecto.

Si está construyendo con Python o Ruby, puede cambiarlo aquí. A continuación, haga clic en el título Cambiar el rol de ejecución predeterminado y seleccione Usar un rol existente .

Ahora seleccione el rol que creamos en el paso anterior del menú desplegable justo debajo de él. Una vez que todos estos estén completos (3.1), haga clic en crear función y esto creará nuestra lambda en un momento.

3.1

 

4. Cree la puerta de enlace API

A continuación, vamos a crear una API Gateway que actuará como la "puerta de entrada" para que nuestras aplicaciones accedan al servicio. Busque API Gateway y en la página del panel, haga clic en crear API.

En el siguiente paso, seleccionamos el tipo de API que vamos a crear. Asegúrese de seleccionar API REST de la lista de opciones proporcionadas y haga clic en compilar (4.1).

4.1

En la página siguiente, asigne un nombre para la puerta de enlace y puede dejar el resto de los valores predeterminados como están y hacer clic en Crear API (4.2)

4.2

Ahora vamos a crear los puntos finales que vamos a utilizar en nuestra aplicación. Primero, haga clic en acciones y cree un recurso en esta API (4.3)

4.3

Proporcione el nombre del recurso y defina su ruta. Aquí vamos a crear uno para iniciar sesión, por lo que nuestra ruta será /login, puede definir la ruta que desee. Asegúrese de hacer clic en Habilitar API Gateway CORS para evitar problemas de CORS en el front-end y haga clic en crear recurso (4.4).

4.4

Ahora vamos a crear el método bajo este recurso. Seleccione el recurso primero y haga clic en crear método de las acciones (4.5)

4.5

De la lista de métodos, seleccione publicar (4.6) ya que esto es lo que vamos a usar para nuestro punto final de API, y haga clic en la marca de verificación junto a él.

4.6

En la configuración, asegúrese de marcar Usar integración de proxy de Lambda para asegurarse de que nuestras solicitudes se envíen a lambda (4.7). Además, seleccione la misma lambda que creamos anteriormente en el menú desplegable a continuación. Puedes dejar el resto de opciones por defecto y hacer clic en guardar.

4.7

Siga los mismos pasos para crear tres puntos finales

  • acceso
  • Registrarse
  • verificar.

Una vez hecho esto, seleccione el recurso raíz y seleccione Implementar API de la lista de acciones.

4.9

Asigne un nombre y una descripción a su etapa de implementación. Haga clic en implementar y su API se implementará en segundos.

4.10

En la página resultante, copie la URL de invocación para su uso posterior y esta será la URL base de nuestra API.

4.11

 

5. Crea el servicio de back-end

En este paso, codificaremos el backend real que contendrá la lógica para nuestro servicio de inicio de sesión. Podemos hacer esto localmente y luego implementarlo en lambda. Para comenzar, cree un nuevo proyecto vacío en VS Code y ejecute npm init para inicializar un proyecto de Node JS. La estructura de carpetas final se verá así.

Ahora configuremos nuestro index.js como controlador para la función lambda. Abra index.js y agregue el siguiente código.

const registerPath = "/register";
const loginPath = "/login";
const verifyPath = "/verify";

const registerService = require("./functions/register");

const loginService = require("./functions/login");

const verifyService = require("./functions/verify");

const util = require("./helpers/utils/util");

exports.handler = async (event) => {
  console.log(" Request Event : ", event);
  const { httpMethod, resource } = event;
  const requestBody = JSON.parse(event.body);
  let response;
  switch (true) {
    case httpMethod === "POST" && resource === registerPath:
      response = await registerService.register(requestBody);
      break;
    case httpMethod === "POST" && resource === loginPath:
      response = await loginService.login(requestBody);
      break;
    case httpMethod === "POST" && resource === verifyPath:
      response = await verifyService.verify(requestBody);
      break;
    default:
      response = util.buildResponse(404, "404 Not Found ");
  }
  return response;
};

Como puede ver, estamos creando un controlador, que compara el método de solicitud con las rutas que hemos definido en nuestra puerta de enlace API y llama al servicio correspondiente. Crearemos servicios individuales para-

  • /registro: toma el nombre, el nombre de usuario y la contraseña del cuerpo de la solicitud y crea un nuevo usuario en la base de datos. Devuelve el nombre de usuario en caso de éxito.
  • inicio de sesión: toma el nombre de usuario y la contraseña del cuerpo de la solicitud y los compara con la base de datos para los usuarios existentes. Devuelve el nombre de usuario y el token JWT en caso de éxito.
  • verificar: toma el nombre de usuario y el token JWT del cuerpo de la solicitud y lo decodifica para verificar que el token sea válido. Devuelve el mensaje verificado junto con la información del usuario si tiene éxito.

Puede encontrar el código para estos métodos aquí en github .

La parte importante de nuestro proyecto es DB Helper, que se conectará a nuestra tabla de DynamoDB para crear un nuevo usuario y también comparar sus credenciales durante el inicio de sesión. Para ello, crearemos un user.jsayudante dentro de la dbHelpercarpeta.

Este asistente contendrá dos métodos, uno para verificar si el usuario existe comparando la clave principal , que es el nombre de usuario. Y un segundo método para guardar un nuevo usuario usando la misma clave principal.

// Load the AWS SDK for Node.js
const AWS = require("aws-sdk");

// Set the region
AWS.config.update({ region: "us-east-1" });

// Create DynamoDB document client
const dynamoDB = new AWS.DynamoDB.DocumentClient({ apiVersion: "2012-08-10" });

const userTable = "user-table";

exports.getUser = async (username) => {
  const params = {
    TableName: userTable,
    Key: {
      username: username,
    },
  };
  return await dynamoDB
    .get(params)
    .promise()
    .then(
      (response) => {
        return response.Item;
      },
      (error) => {
        console.log("Error fetching user", error);
      }
    );
};

exports.saveUser = async (user) => {
  const params = {
    TableName: userTable,
    Key: {
      username: user.username,
    },
    Item: user,
  };

  return await dynamoDB
    .put(params)
    .promise()
    .then(
      (response) => {
        return true;
      },
      (error) => {
        console.log("Error saving user", error);
      }
    );
};

También crearemos authun asistente para generar y verificar tokens JWT durante el inicio de sesión y la verificación. Estamos usando la jsonwebtokenbiblioteca npm para generar tokens de acceso usando un secreto JWT que definimos. Vamos a establecer la caducidad del token en una hora por ahora, pero puede cambiar esto según sus necesidades.

const jwt = require("jsonwebtoken");

exports.generateToken = (userInfo) => {
  if (!userInfo) {
    return null;
  }

  return jwt.sign(userInfo, process.env.JWT_SECRET, {
    expiresIn: "1h",
  });
};

exports.verifyToken = (username, token) => {
  return jwt.verify(token, process.env.JWT_SECRET, (error, response) => {
    if (error) {
      return {
        verified: false,
        message: "Invalid token",
        error: error,
      };
    }

    if (response.username !== username) {
      return {
        verified: false,
        message: "Invalid user",
      };
    }

    return {
      verified: true,
      message: "verified",
    };
  });
};

Una cosa a tener en cuenta aquí es que estamos usando una variable de entorno JWT_SECRETpara codificar el token JWT, lo definiremos más adelante. Hemos utilizado tres paquetes npm en este proyecto:

  • aws-sdk — para conectarse a DynamoDB.
  • bcryptjs — para cifrar la contraseña del usuario antes de almacenarla en la base de datos.
  • jsonwebtoken— Para generar y verificar tokens JWT.

Puede encontrar el código completo del proyecto en este repositorio de GitHub .

 

6. Implemente el código en lambda

Antes de subir el proyecto a lambda, asegúrese de haber ejecutado npm ipara instalar los paquetes que estamos usando. Hay varios métodos para cargar nuestro código lambda, incluidos CLI, extensión de código VS, sin servidor, etc. Por ahora, vamos a cargar el código manualmente desde la consola. Ejecute el comando zip -r ./archive.zip *después de instalar los paquetes npm, para comprimir nuestro proyecto para lambda.

Ahora volvamos a nuestra lambda en la consola de AWS. Aquí puede encontrar la opción cargar desde (6.1) en la pestaña de código de la lambda. Haga clic en él y cargue el archivo zip del proyecto que acaba de crear.

Esto cargará nuestro código e implementará la lambda en unos momentos. Tenga en cuenta que cuando está cargando una nueva versión para una lambda existente, en algunos casos puede tomar un minuto reflejar esos cambios cuando la llama desde su aplicación.

6.1 Subir zip a lambda

 

7. Configurar la clave secreta

Si recuerda el paso 6, necesitamos definir una variable de entorno JWT_SECRETpara codificar el token JWT. Configuremos esta variable de entorno en nuestro Lambda. Vaya a la pestaña de configuración y seleccione Variables de entorno en el menú de la izquierda.

Haga clic en editar y cree una nueva variable de entorno con el mismo nombre que usamos en nuestro código (7.1). Puede definir su clave secreta, pero recuerde nunca compartirla con nadie ni mantener el valor de la clave en su código. Guarde esta clave y nuestra API ya está lista.

7.1

 

8. Pruebas del cartero

Ahora deja nuestras APIs una por una desde el cartero y comprueba si todo funciona sin problemas. Puede usar la URL de API que copiamos al final del paso 4 o ir a su puerta de enlace de API y copiar la URL (4.11).

Primero, creemos un nuevo usuario usando la API de registro. Como puede ver, estamos pasando el nombre, el nombre de usuario y la contraseña como entradas, y devolvemos el nombre de usuario creado en caso de éxito (8.1)

8.1

También verifiquemos que el usuario haya creado nuestra tabla DynamoDB. Vaya a la mesa desde la consola y haga clic en explorar elementos de la mesa (8.2). Si ejecuta un escaneo, puede ver que la entrada del usuario se ha creado en la tabla.

8.2

Podemos probar nuestra API de inicio de sesión con las mismas credenciales para generar un token de acceso (8.3).

8.3

Y finalmente, use la API de verificación para validar el token contra un usuario (8.4).

8.4

Puede importar la colección completa de cartero aquí , pero recuerde actualizar la URL base con la URL de su API.

Esta historia se publicó originalmente en https://betterprogramming.pub/build-a-serverless-login-service-using-aws-dynamodb-and-lambda-d2ee9bc2e60e

#serverless #token #aws #dynamodb #lambda 

What is GEEK

Buddha Community

Servicio De inicio De Sesión Sin Servidor Con AWS DynamoDB Y Lambda
Diego  Elizondo

Diego Elizondo

1654286700

Servicio De inicio De Sesión Sin Servidor Con AWS DynamoDB Y Lambda

Es 2022, serverless ya no es un término elegante que usan los fanáticos de la tecnología. Cada vez más personas se dan cuenta de que es el camino a seguir para crear aplicaciones rápidas y altamente escalables.

En este artículo, nos centraremos en crear un sistema de inicio de sesión sin servidor desde cero con AWS, utilizando dos de sus servicios populares:

Si ya tiene mucha experiencia con estos dos, lo cual supongo que no porque ha leído el título, el siguiente tutorial puede no ser para usted. Antes de comenzar, necesitará una cuenta de AWS para este proyecto, puede registrarse para obtener una aquí . Echemos un vistazo al sistema que vamos a construir.

Como puede ver, crearemos un servicio de inicio de sesión básico que utiliza una puerta de enlace API para acceder a la lambda que se conectará a DynamoDB. Tendremos tres puntos finales en nuestros proyectos, el primero es para registrar un nuevo usuario y almacenar los detalles en la base de datos. El segundo sería para el inicio de sesión del usuario y la emisión de un token JWT para el usuario. Y el tercero es verificar que el token sea válido. Empecemos.

1. Creación de una tabla de DynamoDB

El primer paso que vamos a dar es crear una tabla de DynamoDB donde almacenaremos nuestros datos de usuario.

Como se mencionó anteriormente, DynamoDB es una base de datos NoSQL, los datos se almacenan y consultan principalmente mediante una clave principal , que será la clave de partición y, en algunos casos, una combinación de clave de partición y clave de ordenación.

DynamoDB utiliza el valor de la clave de partición como entrada para una función hash interna que decide la partición en la que se almacenarán sus datos. Puede leer más sobre las claves aquí , ya que sería demasiado para cubrir en este artículo.

Para crear una tabla, vaya a su consola de AWS y busque DynamoDB en el cuadro de búsqueda superior y selecciónelo en los resultados de búsqueda. Una vez que esté en el panel de DynamoDB, haga clic en la opción Crear tabla (1.1)

1.1

Esto lo llevará a una página donde se le pedirá que proporcione los detalles de la tabla, como el nombre de la tabla y las claves principales (1.2).

Vamos a nombrar nuestra tabla user-table por ahora y definir el nombre de usuario como nuestra clave de partición, que es lo que usaremos para buscar usuarios. Puede ver que la clave de clasificación es opcional, la dejaremos en blanco ya que no es necesaria para nuestra aplicación simple.

1.2

Puede dejar el resto de la configuración con los valores predeterminados y hacer clic en crear tabla al final de la página. Esto creará su tabla en unos momentos. Ahora que la base de datos está lista, pasemos al siguiente paso.

2. Creación del rol de IAM

Para crear un rol de IAM, busque IAM en el cuadro de búsqueda superior y una vez que esté en el tablero, vaya a Roles desde el panel izquierdo (2.1) para crear un nuevo rol y haga clic en crear el rol.

2.1

En el paso 1, puede seleccionar Lambda de los casos de uso comunes (2.2), ya que para eso usaremos nuestro rol y pasar al siguiente paso.

2.2

En el siguiente paso, debemos agregar permisos para nuestro rol. Para este proyecto, vamos a agregar dos permisos.

El primero es para Dynamo DB y el otro para CloudWatch. Para agregarlos, simplemente busque Dynamo DB en el cuadro de búsqueda y seleccione el permiso de acceso completo de DynamoDB de la lista (2.3).

2.3

A continuación, busque el acceso completo de CloudWatch y agréguelo también. Vamos a usar CloudWatch para ver los registros de nuestra función lambda.

En el siguiente paso, asigne un nombre al rol que estamos creando y haga clic en crear rol al final de la página.

Esto creará un rol de IAM que conectaremos a nuestro lambda, lo que le permitirá conectarse a DynamoDB y CloudWatch sin problemas. Ahora pasemos al siguiente paso.

 

3. Crea la lambda

Ahora vamos a crear la lambda que servirá como backend para nuestras API. Busque lambda en el cuadro de búsqueda superior y haga clic en crear función una vez que esté en el panel de control de lambda.

En el siguiente paso, asigne un nombre al servicio lambda y deje el tiempo de ejecución predeterminado como Node.js, ya que eso es lo que usaremos para este proyecto.

Si está construyendo con Python o Ruby, puede cambiarlo aquí. A continuación, haga clic en el título Cambiar el rol de ejecución predeterminado y seleccione Usar un rol existente .

Ahora seleccione el rol que creamos en el paso anterior del menú desplegable justo debajo de él. Una vez que todos estos estén completos (3.1), haga clic en crear función y esto creará nuestra lambda en un momento.

3.1

 

4. Cree la puerta de enlace API

A continuación, vamos a crear una API Gateway que actuará como la "puerta de entrada" para que nuestras aplicaciones accedan al servicio. Busque API Gateway y en la página del panel, haga clic en crear API.

En el siguiente paso, seleccionamos el tipo de API que vamos a crear. Asegúrese de seleccionar API REST de la lista de opciones proporcionadas y haga clic en compilar (4.1).

4.1

En la página siguiente, asigne un nombre para la puerta de enlace y puede dejar el resto de los valores predeterminados como están y hacer clic en Crear API (4.2)

4.2

Ahora vamos a crear los puntos finales que vamos a utilizar en nuestra aplicación. Primero, haga clic en acciones y cree un recurso en esta API (4.3)

4.3

Proporcione el nombre del recurso y defina su ruta. Aquí vamos a crear uno para iniciar sesión, por lo que nuestra ruta será /login, puede definir la ruta que desee. Asegúrese de hacer clic en Habilitar API Gateway CORS para evitar problemas de CORS en el front-end y haga clic en crear recurso (4.4).

4.4

Ahora vamos a crear el método bajo este recurso. Seleccione el recurso primero y haga clic en crear método de las acciones (4.5)

4.5

De la lista de métodos, seleccione publicar (4.6) ya que esto es lo que vamos a usar para nuestro punto final de API, y haga clic en la marca de verificación junto a él.

4.6

En la configuración, asegúrese de marcar Usar integración de proxy de Lambda para asegurarse de que nuestras solicitudes se envíen a lambda (4.7). Además, seleccione la misma lambda que creamos anteriormente en el menú desplegable a continuación. Puedes dejar el resto de opciones por defecto y hacer clic en guardar.

4.7

Siga los mismos pasos para crear tres puntos finales

  • acceso
  • Registrarse
  • verificar.

Una vez hecho esto, seleccione el recurso raíz y seleccione Implementar API de la lista de acciones.

4.9

Asigne un nombre y una descripción a su etapa de implementación. Haga clic en implementar y su API se implementará en segundos.

4.10

En la página resultante, copie la URL de invocación para su uso posterior y esta será la URL base de nuestra API.

4.11

 

5. Crea el servicio de back-end

En este paso, codificaremos el backend real que contendrá la lógica para nuestro servicio de inicio de sesión. Podemos hacer esto localmente y luego implementarlo en lambda. Para comenzar, cree un nuevo proyecto vacío en VS Code y ejecute npm init para inicializar un proyecto de Node JS. La estructura de carpetas final se verá así.

Ahora configuremos nuestro index.js como controlador para la función lambda. Abra index.js y agregue el siguiente código.

const registerPath = "/register";
const loginPath = "/login";
const verifyPath = "/verify";

const registerService = require("./functions/register");

const loginService = require("./functions/login");

const verifyService = require("./functions/verify");

const util = require("./helpers/utils/util");

exports.handler = async (event) => {
  console.log(" Request Event : ", event);
  const { httpMethod, resource } = event;
  const requestBody = JSON.parse(event.body);
  let response;
  switch (true) {
    case httpMethod === "POST" && resource === registerPath:
      response = await registerService.register(requestBody);
      break;
    case httpMethod === "POST" && resource === loginPath:
      response = await loginService.login(requestBody);
      break;
    case httpMethod === "POST" && resource === verifyPath:
      response = await verifyService.verify(requestBody);
      break;
    default:
      response = util.buildResponse(404, "404 Not Found ");
  }
  return response;
};

Como puede ver, estamos creando un controlador, que compara el método de solicitud con las rutas que hemos definido en nuestra puerta de enlace API y llama al servicio correspondiente. Crearemos servicios individuales para-

  • /registro: toma el nombre, el nombre de usuario y la contraseña del cuerpo de la solicitud y crea un nuevo usuario en la base de datos. Devuelve el nombre de usuario en caso de éxito.
  • inicio de sesión: toma el nombre de usuario y la contraseña del cuerpo de la solicitud y los compara con la base de datos para los usuarios existentes. Devuelve el nombre de usuario y el token JWT en caso de éxito.
  • verificar: toma el nombre de usuario y el token JWT del cuerpo de la solicitud y lo decodifica para verificar que el token sea válido. Devuelve el mensaje verificado junto con la información del usuario si tiene éxito.

Puede encontrar el código para estos métodos aquí en github .

La parte importante de nuestro proyecto es DB Helper, que se conectará a nuestra tabla de DynamoDB para crear un nuevo usuario y también comparar sus credenciales durante el inicio de sesión. Para ello, crearemos un user.jsayudante dentro de la dbHelpercarpeta.

Este asistente contendrá dos métodos, uno para verificar si el usuario existe comparando la clave principal , que es el nombre de usuario. Y un segundo método para guardar un nuevo usuario usando la misma clave principal.

// Load the AWS SDK for Node.js
const AWS = require("aws-sdk");

// Set the region
AWS.config.update({ region: "us-east-1" });

// Create DynamoDB document client
const dynamoDB = new AWS.DynamoDB.DocumentClient({ apiVersion: "2012-08-10" });

const userTable = "user-table";

exports.getUser = async (username) => {
  const params = {
    TableName: userTable,
    Key: {
      username: username,
    },
  };
  return await dynamoDB
    .get(params)
    .promise()
    .then(
      (response) => {
        return response.Item;
      },
      (error) => {
        console.log("Error fetching user", error);
      }
    );
};

exports.saveUser = async (user) => {
  const params = {
    TableName: userTable,
    Key: {
      username: user.username,
    },
    Item: user,
  };

  return await dynamoDB
    .put(params)
    .promise()
    .then(
      (response) => {
        return true;
      },
      (error) => {
        console.log("Error saving user", error);
      }
    );
};

También crearemos authun asistente para generar y verificar tokens JWT durante el inicio de sesión y la verificación. Estamos usando la jsonwebtokenbiblioteca npm para generar tokens de acceso usando un secreto JWT que definimos. Vamos a establecer la caducidad del token en una hora por ahora, pero puede cambiar esto según sus necesidades.

const jwt = require("jsonwebtoken");

exports.generateToken = (userInfo) => {
  if (!userInfo) {
    return null;
  }

  return jwt.sign(userInfo, process.env.JWT_SECRET, {
    expiresIn: "1h",
  });
};

exports.verifyToken = (username, token) => {
  return jwt.verify(token, process.env.JWT_SECRET, (error, response) => {
    if (error) {
      return {
        verified: false,
        message: "Invalid token",
        error: error,
      };
    }

    if (response.username !== username) {
      return {
        verified: false,
        message: "Invalid user",
      };
    }

    return {
      verified: true,
      message: "verified",
    };
  });
};

Una cosa a tener en cuenta aquí es que estamos usando una variable de entorno JWT_SECRETpara codificar el token JWT, lo definiremos más adelante. Hemos utilizado tres paquetes npm en este proyecto:

  • aws-sdk — para conectarse a DynamoDB.
  • bcryptjs — para cifrar la contraseña del usuario antes de almacenarla en la base de datos.
  • jsonwebtoken— Para generar y verificar tokens JWT.

Puede encontrar el código completo del proyecto en este repositorio de GitHub .

 

6. Implemente el código en lambda

Antes de subir el proyecto a lambda, asegúrese de haber ejecutado npm ipara instalar los paquetes que estamos usando. Hay varios métodos para cargar nuestro código lambda, incluidos CLI, extensión de código VS, sin servidor, etc. Por ahora, vamos a cargar el código manualmente desde la consola. Ejecute el comando zip -r ./archive.zip *después de instalar los paquetes npm, para comprimir nuestro proyecto para lambda.

Ahora volvamos a nuestra lambda en la consola de AWS. Aquí puede encontrar la opción cargar desde (6.1) en la pestaña de código de la lambda. Haga clic en él y cargue el archivo zip del proyecto que acaba de crear.

Esto cargará nuestro código e implementará la lambda en unos momentos. Tenga en cuenta que cuando está cargando una nueva versión para una lambda existente, en algunos casos puede tomar un minuto reflejar esos cambios cuando la llama desde su aplicación.

6.1 Subir zip a lambda

 

7. Configurar la clave secreta

Si recuerda el paso 6, necesitamos definir una variable de entorno JWT_SECRETpara codificar el token JWT. Configuremos esta variable de entorno en nuestro Lambda. Vaya a la pestaña de configuración y seleccione Variables de entorno en el menú de la izquierda.

Haga clic en editar y cree una nueva variable de entorno con el mismo nombre que usamos en nuestro código (7.1). Puede definir su clave secreta, pero recuerde nunca compartirla con nadie ni mantener el valor de la clave en su código. Guarde esta clave y nuestra API ya está lista.

7.1

 

8. Pruebas del cartero

Ahora deja nuestras APIs una por una desde el cartero y comprueba si todo funciona sin problemas. Puede usar la URL de API que copiamos al final del paso 4 o ir a su puerta de enlace de API y copiar la URL (4.11).

Primero, creemos un nuevo usuario usando la API de registro. Como puede ver, estamos pasando el nombre, el nombre de usuario y la contraseña como entradas, y devolvemos el nombre de usuario creado en caso de éxito (8.1)

8.1

También verifiquemos que el usuario haya creado nuestra tabla DynamoDB. Vaya a la mesa desde la consola y haga clic en explorar elementos de la mesa (8.2). Si ejecuta un escaneo, puede ver que la entrada del usuario se ha creado en la tabla.

8.2

Podemos probar nuestra API de inicio de sesión con las mismas credenciales para generar un token de acceso (8.3).

8.3

Y finalmente, use la API de verificación para validar el token contra un usuario (8.4).

8.4

Puede importar la colección completa de cartero aquí , pero recuerde actualizar la URL base con la URL de su API.

Esta historia se publicó originalmente en https://betterprogramming.pub/build-a-serverless-login-service-using-aws-dynamodb-and-lambda-d2ee9bc2e60e

#serverless #token #aws #dynamodb #lambda 

Royce  Reinger

Royce Reinger

1619684055

Triggering AWS Lambda Events with DynamoDB Integration

This is a basic introduction to Lambda triggers that uses DynamoDB as an event source example.

We talk a lot about the more advanced level of Lambda triggers in our popular two-part series: Complete Guide to Lambda Triggers.

We’re going back to the basics this time because skipping some steps when learning something new might get you confused. It tends to get annoying, or it can even make you frustrated. Why?

To understand how something works appropriately and later on to know how to apply your knowledge practically without stress, you must master the particular subject in a particular order.

Let me put it this way: you can’t calculate how fast is a subatomic particle moving in space if it’s 300 lightyears away from the closest planet if you don’t know the basic math, like 3.14 times 42, right?

So, back to our topic here, what are AWS Lambda triggers?

Lambda Triggers Explained with DynamoDB Integration

DynamoDB is an AWS product just like Lambda, and therefore you’re able to create triggers with ease. Triggers are pieces of code that will automatically respond to any events in DynamoDB Streams.

Triggers allow you to build applications that will then react to any data modification made in DynamoDB tables. By enabling DynamoDB Streams on a table, you will be able to associate an ARN with your Lambda function. Instantly after an item in the table is modified, a new record will appear in the table’s stream. When AWS Lambda detects a new stream record, it will invoke your Lambda function synchronously.

Lambda functions can perform any actions you specify, like sending notifications or a workflow initiation.

An example: suppose you have a mobile gaming app that’s writing on a GameScores table. Each time the TopScore attribute of the GameScores table is updated, a corresponding stream record will be written to the table’s stream. You can then set a Lambda function to post a message on social media sites once the event is triggered.

#aws-lambda #aws #aws-services #dynamodb #serverless

Saul  Alaniz

Saul Alaniz

1653392640

AWS SAM: Configuración Del Desarrollo Sin Servidor Local Con Lambda

AWS SAM significa Modelo de aplicación sin servidor. Es un marco sin servidor para los recursos de AWS exclusivamente. Se utiliza para definir, probar e implementar aplicaciones sin servidor. Las plantillas de SAM pueden parecerse a CloudFormation, y con razón, porque CloudFormation se encuentra debajo y se encarga de la parte de implementación.

Cuando implementa nuestra pila completamente definida (funciones lambda, roles, depósitos S3, bases de datos nativas sin servidor), puede probarla mientras se implementa en un entorno de nube en la etapa de no producción (y puede incurrir en cargos). El proceso de desarrollo podría ser más rápido y económico al ejecutar todo localmente, y creará una configuración de este tipo en este artículo.

Preparación

Requisitos

Inicializar un proyecto

Puede explorar todas las plantillas o escribir desde cero usando sam init, pero comenzaremos con la plantilla de "API sin servidor" proporcionada por AWS.

sam init --name my-sam-app --runtime nodejs14.x --app-template quick-start-web

Visión de conjunto

Ahora, echemos un vistazo rápido a template.yaml, que describe la configuración. Tu objetivo es comprender los recursos en solo 20 segundos. ¡Muy bien, empieza!

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  sam-sam-app
Transform:
- AWS::Serverless-2016-10-31

Resources:
  getAllItemsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/get-all-items.getAllItemsHandler
      # ...
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref SampleTable
      Environment:
        Variables:
          SAMPLE_TABLE: !Ref SampleTable
      Events:
        Api:
          Type: Api
          Properties:
            Path: /
            Method: GET
            
  getByIdFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/get-by-id.getByIdHandler
      # ...
      Events:
        Api:
          Type: Api
          Properties:
            Path: /{id}
            Method: GET

  putItemFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/put-item.putItemHandler
      # ...
      Events:
        Api:
          Type: Api
          Properties:
            Path: /
            Method: POST

  SampleTable:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
        Name: id
        Type: String
      # ...

Outputs:
  WebEndpoint:
    Description: "API Gateway endpoint URL for Prod stage"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"

Versión legible para efectos del artículo. Encuentre el archivo completo en su directorio de trabajo.

Pocas funciones CRUD y una tabla DynamoDB. No necesita definir los recursos y roles de la puerta de enlace API en este marco, lo que lo hace mucho más simple que el equivalente de Terraform.

Intentando invocar eventos localmente

Puede verificar si las funciones funcionan utilizando eventos simulados.

Elijamos una getAllItemsFunctionfunción de la plantilla y un evento relacionado de events/. Debería devolver una matriz vacía porque aún no se han insertado elementos.

sam local invoke getAllItemsFunction -e events/event-get-all-items.json

Desafortunadamente, obtenemos:

Invoke Error  {"errorType":"ResourceNotFoundException","errorMessage":"Requested resource not found"...

Sucede porque no tenemos DynamoDB localmente.

Mire estas pocas líneas extraídas del controlador de funciones src/handlers/get-all-items.js:

const dynamodb = require('aws-sdk/clients/dynamodb');
const docClient = new dynamodb.DocumentClient();
//...
exports.getAllItemsHandler = async (event) => {
  //...
  const data = await docClient.scan({ TableName : process.env.SAMPLE_TABLE }).promise();
  //...
}

AWS SDK (importado en la primera línea) depende del contexto de ejecución y encuentra mágicamente el servicio de DynamoDB relacionado cuando se implementa en la nube. Localmente, no encuentra nada.

Solución

Agregar DynamoDB localmente

Ejecute DynamoDB en Docker utilizando la imagen oficial de AWS. Aquí está el comando:

docker run -p 8000:8000 amazon/dynamodb-local

Ajustar controlador de función

Cambie la docClientdeclaración en las primeras líneas desrc/handlers/get-all-items.js

// const docClient = new dynamodb.DocumentClient()
const docClient = process.env.AWS_SAM_LOCAL ? new dynamodb.DocumentClient({
  endpoint: "http://host.docker.internal:8000"
}) : new dynamodb.DocumentClient()

Cambiará la conexión utilizada según el entorno SAM de AWS, luego apuntará al DynamoDB local.

Estamos usando host.docker.internalen lugar de localhostporque el iniciador de eventos de AWS SAM ya está en un contenedor acoplable. De esta forma, obtenemos la dirección de la máquina host desde un contenedor invitado. Alucinante, lo sé.

Crear una tabla localmente

Estamos utilizando el SimpleTablerecurso, que representa una tabla en DynamoDB. Se crea o usa automáticamente (si existe), pero debemos crearlo localmente.

Utilice el nombre SampleTablede la tabla para que la tabla local cumpla automáticamente con template.yamllos controladores existentes.

Haga lo mismo con los atributos y las claves: use el iddefinido entemplate.yaml

aws dynamodb create-table --table-name SampleTable --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --billing-mode PAY_PER_REQUEST --endpoint-url http://localhost:8000

Compruebe si se crea con lo siguiente:

aws dynamodb list-tables --endpoint-url http://localhost:8000

Vuelva a ejecutar el evento de prueba

$ sam local invoke getAllItemsFunction -e events/event-get-all-items.json[...]{"statusCode":200,"body":"[]"}

Solicitud procesada. El cuerpo es de hecho una matriz vacía. ¡Lo hiciste! 🏆

Ahora puede seguir desarrollando sus funciones lambda con la base de datos conectada. Si está listo para comenzar a vivir, puede hacerlo con sam deploy.

Resumen

En este artículo tienes:

  1. Comprensión de los conceptos básicos de AWS SAM
  2. Integración de DynamoDB agregada localmente
  3. Configuración de desarrollo local preparada para su hermosa aplicación

En algunos escenarios, se necesita demasiado esfuerzo para crear un entorno local completamente integrado para el desarrollo sin servidor. Tiene que haber cambios en la base del código que cambien las variables dependiendo de si se ejecutan de forma local o remota.

Puede resultar en inconsistencias que se conviertan en un código que funciona perfectamente localmente pero falla en la nube. Considere si necesita toda la integración localmente o si CI/CD debe encargarse de las pruebas de integración.

Además de eso, DynamoDB tiene una integración local fluida porque AWS proporciona la imagen de la ventana acoplable. La configuración con otros recursos menos comunes puede ser engorrosa.

Cree un bot de Discord con AWS Lambda + API Gateway

¿Qué marco sin servidor está utilizando y cómo simplifica su desarrollo?

¡Déjame saber abajo en los comentarios!

Fuente: https://betterprogramming.pub/

#aws #dynamodb #lambda 

Cross-account access to invoke AWS lambda using AWS CDK

If you are here, you may have a pretty good knowledge of how to use AWS CDK for defining cloud infrastructure in code and provisioning it through AWS. So let’s get started on how to grant permission to your lambda function to access the resources in another AWS account.

Let’s say you have two accounts called Account A and Account B, and you need to give permission to lambda function in Account A (ex: 11111111)to access the resources in Account B(22222222). You can easily do this by assuming an IAM Role in Account B and then uses the returned credentials to invoke AWS resources in Account B.

#acces #account #aws #lambda #aws lambda #aws cdk

藤本  結衣

藤本 結衣

1591878120

[AWS CDK超入門] DynamoDB + Lambda + API GatewayでAPIを作ってみた | Developers.IO

AWS CDK とは AWS Cloud Development Kit (AWS CDK)は AWS のリソースを Typescript や Python 等のコードで定義するフレームワークです。コードで定義したリソー […]

#aws #aws cdk #dynamodb #lambda #api