Saltar al contenido principal
Como parte del escenario de arquitectura de servidor + API, implementaremos la API de Timesheets en Node.js. Consulta el escenario para obtener más información sobre la solución implementada. El código fuente completo de la implementación de la API en Node.js está disponible en este repositorio de GitHub.

Paso 1. Define el endpoint de la API

Usaremos el framework de aplicaciones web Express para crear nuestra API de Node.js.

Cree un archivo package.json

Cree una carpeta para su API, acceda a ella y ejecute npm init. Esto generará el archivo package.json. Puede dejar la configuración predeterminada o cambiarla según le convenga. El archivo package.json de nuestro ejemplo es el siguiente:
{
  "name": "timesheets-api",
  "version": "1.0.0",
  "description": "API used to add timesheet entries for employees and contractors",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/auth0-samples/auth0-pnp-timesheets.git"
  },
  "author": "Auth0",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/auth0-samples/auth0-pnp-timesheets/issues"
  },
  "homepage": "https://github.com/auth0-samples/auth0-pnp-timesheets#readme"
}

Instale las dependencias

A continuación, debemos definir nuestras dependencias. Usaremos los siguientes módulos:
  • express: Este módulo agrega el framework web Express.
  • jwks-rsa: Esta biblioteca recupera claves de firma RSA desde un endpoint JWKS (JSON Web Key Set). Mediante expressJwtSecret, podemos generar un proveedor de secretos que proporcionará la clave de firma correcta a express-jwt en función del kid del encabezado . Para obtener más información, consulte el repositorio de GitHub de node-jwks-rsa.
  • express-jwt: Este módulo le permite autenticar solicitudes HTTP mediante tokens JWT en sus aplicaciones de Node.js. Proporciona varias funciones que facilitan el trabajo con JWT. Para obtener más información, consulte el repositorio de GitHub de express-jwt.
  • body-parser: Este es un middleware de análisis del cuerpo para Node.js. Extrae por completo el cuerpo de un flujo de solicitud entrante y lo expone en req.body de una forma más fácil de usar. Para obtener más información y varias alternativas, consulte el repositorio de GitHub de body-parser.
Para instalar estas dependencias, ejecute lo siguiente:
npm install express express-jwt jwks-rsa body-parser --save

Implementa el endpoint

Ve al directorio de tu API y crea un archivo server.js. Tu código debe:
  • Configurar las dependencias.
  • Habilitar el middleware para analizar el cuerpo de la solicitud.
  • Implementar el endpoint.
  • Iniciar el servidor de la API.
Esta es una implementación de ejemplo:
// establecer dependencias
const express = require('express');
const app = express();
const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');
const bodyParser = require('body-parser');

// habilitar el uso del middleware de análisis del cuerpo de la solicitud
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

// crear el endpoint de la API para subir hojas de horas
app.post('/timesheets/upload', function(req, res){
  res.status(201).send({message: "This is the POST /timesheets/upload endpoint"});
})

// iniciar el servidor de la API en localhost:8080
app.listen(8080);
Inicie su servidor API con node server y haga una solicitud HTTP POST a localhost:8080/timesheets/upload. Debería ver una respuesta JSON con el mensaje This is the POST /timesheets/upload endpoint. Ahora ya tenemos el endpoint, pero cualquiera puede llamarlo. Continúe con el siguiente párrafo para ver cómo podemos solucionarlo.

Paso 2. Proteger el endpoint de la API

Para validar nuestro token, usaremos la función jwt, proporcionada por el middleware express-jwt, y el paquete jwks-rsa para obtener la clave pública de Auth0. Estas bibliotecas hacen lo siguiente:
  1. express-jwt decodificará el token y pasará la solicitud, el encabezado y la carga útil a jwksRsa.expressJwtSecret.
  2. jwks-rsa descargará entonces todas las claves de firma del endpoint JWKS y comprobará si alguna de ellas coincide con el kid del encabezado del JWT. Si ninguna de las claves de firma coincide con el kid recibido, se generará un error. Si hay coincidencia, pasaremos la clave de firma correcta a express-jwt.
  3. express-jwt continuará con su propia lógica para validar la firma del token, la expiración, la audience y el issuer.
Los pasos que seguiremos en nuestro código son:
  • Crear la función de middleware para validar el .
  • Habilitar el uso del middleware en nuestras rutas.
Este es también un buen momento para implementar la lógica para guardar los registros de horas en una base de datos local, o en cualquier otro mecanismo de almacenamiento que prefieras. Esta es nuestra implementación de ejemplo (se omite parte del código por brevedad): Si iniciamos el servidor ahora y hacemos una solicitud HTTP POST a localhost:8080/timesheets/upload, deberíamos recibir el mensaje de error Missing or invalid token (lo cual es perfectamente normal, ya que no enviamos ningún token de acceso en la solicitud). Para probar también el escenario correcto, necesitamos:
  • Obtener un token de acceso. Para obtener más información sobre cómo hacerlo, consulta: Obtener un token de acceso
  • Invocar la API añadiendo un encabezado Authorization a la solicitud con el valor Bearer ACCESS_TOKEN (donde ACCESS_TOKEN es el valor del token que obtuvimos en el primer paso).

Paso 3. Verifique los permisos del cliente

En este paso, agregaremos a nuestra implementación la capacidad de comprobar si el cliente tiene permisos (o scope) para usar nuestro endpoint y subir una hoja de horas. En concreto, queremos asegurarnos de que el token tenga el scope correcto, que es batch:upload. Para ello, usaremos el paquete de Node.js express-jwt-authz, así que agréguelo a su proyecto:
npm install express-jwt-authz --save
Ahora es tan sencillo como añadir una llamada a jwtAuthz(...) a tu middleware para asegurarte de que el JWT contenga un scope determinado antes de ejecutar un endpoint concreto. Esta es nuestra implementación de ejemplo (se omite parte del código por brevedad):
// establecer dependencias - parte del código omitido
const jwtAuthz = require('express-jwt-authz');

// Crear middleware para verificar el JWT

// Habilitar el uso del middleware de análisis del cuerpo de la solicitud
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

// Endpoint de carga por lotes
app.post('/timesheets/upload', checkJwt, jwtAuthz(['batch:upload']), function(req, res){
  var timesheet = req.body;

  // Guardar la entrada de la hoja de horas en la base de datos...

  //enviar la respuesta
  res.status(201).send(timesheet);
});

// iniciar el servidor de API en localhost:8080 - código omitido
Si invocamos nuestra API con un token que no incluye este scope, deberíamos recibir el mensaje de error Forbidden con el código de estado HTTP 403. Puede comprobarlo eliminando este scope de su API. ¡Eso es todo! ¡Ha terminado!