Asegura tus recursos de API para la comunicación de máquina a máquina
Aprende cómo aprovechar OAuth 2.0 y JWT para asegurar tus recursos de API para la comunicación de máquina a máquina.
Aprende cómo aprovechar OAuth 2.0 y JWT para asegurar tus recursos de API para la comunicación de máquina a máquina.
Cuando construyes un proyecto que involucra múltiples servicios, la seguridad de los recursos de la API es una preocupación crítica. En este artículo, te mostraré cómo aprovechar OAuth 2.0 y JWT para asegurar la comunicación entre servicios (de máquina a máquina) y cómo aplicar control de acceso basado en roles (RBAC) para seguir el principio del mínimo privilegio.
Para seguir adelante, asumo que tienes los siguientes requisitos previos:
Para fines de demostración, asumamos que tenemos los siguientes servicios:
https://cart.example.com/apihttps://payment.example.com/apiAhora, nuestro servicio de carrito necesita llamar al servicio de pagos para procesar pagos. El flujo de autenticación es el siguiente:
Algunos conceptos clave en el diagrama anterior:
Cada participante en el diagrama anterior tiene un rol en el flujo de autenticación:
Vamos a recorrer el flujo de autenticación paso a paso.
Para realizar el flujo de autenticación, necesitamos crear una aplicación de máquina a máquina (servicio de carrito) y un recurso de API (servicio de pagos) en Logto.
Ya que nuestro servicio de carrito necesita estar al tanto de la API del servicio de pagos al realizar la autenticación, primero necesitamos crear un recurso de API. Ve a la Consola de Logto, haz clic en Recursos de API en la barra lateral izquierda y luego en Crear recurso de API. En el diálogo que se abre, ofrecemos algunos tutoriales para ayudarte a comenzar. También puedes hacer clic en Continuar sin tutorial para omitirlo.
Introduce el nombre del API y el identificador, por ejemplo, Servicio de pagos y https://payment.example.com/api, luego haz clic en Crear recurso de API.
Después de crear el recurso de API, serás redirigido a la página de detalles. Podemos dejarlo tal cual por ahora.
Haz clic en Aplicaciones en la barra lateral izquierda, y luego en Crear aplicación. En el diálogo que se abre, busca la tarjeta Máquina a máquina, luego haz clic en Comenzar a construir.
Introduce el nombre de la aplicación, por ejemplo, Servicio de carrito, y haz clic en Crear aplicación. Se mostrará una guía interactiva para ayudarte a configurar la aplicación. Puedes seguir la guía para entender el uso básico, o hacer clic en Finalizar y listo para omitirla.
Dado que se supone que las aplicaciones de máquina a máquina son seguras (por ejemplo, están desplegadas en una red privada), podemos usar la concesión "client_credentials" de OAuth 2.0 para obtener un token de acceso. Usa autenticación básica para autenticar al cliente:
POST.Content-Type de la solicitud es application/x-www-form-urlencoded.Authorization, el valor es Basic <base64(app_id:app_secret)>, donde app_id y app_secret son el ID y el secreto de la aplicación de máquina a máquina respectivamente. Puedes encontrarlos en la página de detalles de la aplicación.grant_type=client_credentials&resource=https://payment.example.com/api.
grant_type=client_credentials: El valor constante para la concesión "client_credentials".resource=https://payment.example.com/api: El identificador de la API del recurso que el cliente quiere acceder.scope=read:payment write:payment. Cubriremos los ámbitos más adelante.Aquí tienes un ejemplo de la solicitud usando curl:
Un cuerpo de respuesta exitoso sería como:
Ahora tenemos el token de acceso, y podemos añadirlo al encabezado Authorization de la solicitud al recurso de API. Por ejemplo, si queremos llamar a la API POST /payments del servicio de pagos, podemos enviar la siguiente solicitud:
Puedes notar que el servicio de pagos necesita validar el JWT usando el conjunto JWK, y puede tener una caché local de conjunto JWK para evitar obtener el conjunto JWK de Logto cada vez. Afortunadamente, debido a la popularidad de JWT, hay muchas bibliotecas que pueden ayudarte a lograr esto con varias líneas de código.
Estas bibliotecas se llaman habitualmente "jose" (Firmado y Cifrado de Objetos JavaScript) o "jsonwebtoken". Por ejemplo, en Node.js podemos usar jose para validar el JWT:
Si la validación tiene éxito, la variable payload será la carga útil decodificada de JWT. De lo contrario, se lanzará un error.
Ahora hemos asegurado exitosamente la comunicación entre el servicio de carrito y el servicio de pagos. Sin embargo, el flujo de autenticación solo asegura que el cliente es el servicio de carrito real, pero no asegura que el servicio de carrito tenga permiso para realizar acciones en el servicio de pagos.
Digamos que queremos permitir que el servicio de carrito cree pagos, pero no que lea pagos.
En Logto, "scopes" y "permissions" son intercambiables. Ve a la página de detalles del recurso de API del servicio de pagos y navega a la pestaña Permisos. Debería estar vacía ahora. Haz clic en Crear permiso, introduce read:payment como nombre del permiso e introduce Leer pagos como descripción del permiso. Luego haz clic en Crear permiso.
Repite los pasos anteriores para crear otro permiso con el nombre write:payment y la descripción Crear pagos.
Un rol es un grupo de permisos. En Logto, las aplicaciones de máquina a máquina pueden asignarse roles para otorgar permisos. Haz clic en "Roles" en la barra lateral izquierda, y luego en Crear rol.
checkout como nombre del rol e introduce Servicio de caja como descripción del rol.write:payment.


Además de los parámetros del cuerpo de la solicitud que mencionamos en Solicitar token de acceso, también podemos especificar los ámbitos en el cuerpo de la solicitud. Por ejemplo, si queremos solicitar el permiso write:payment, podemos enviar la siguiente solicitud:
Para solicitar múltiples ámbitos, puedes separarlos con espacios. Por ejemplo, scope=write:payment read:payment.
Si una acción necesita el permiso write:payment en el servicio de pagos, podemos validar los ámbitos asegurándonos de que el reclamo scope de la carga útil JWT:
Si quieres proteger el acceso al servicio de carrito, también puedes aplicar el mismo flujo de autenticación. Esta vez, el servicio de carrito es el recurso de API, y el cliente es otro servicio que necesita acceder.
Con Logto, tus recursos de API están asegurados con OAuth 2.0 y JWT, y puedes seguir el principio del mínimo privilegio aplicando control de acceso basado en roles. Además, también puedes usar Logto para gestionar tus usuarios y sus permisos, e incluso integrar con proveedores de identidad de terceros.