https://d226lax1qjow5r.cloudfront.net/blog/blogposts/curl-https-nexmo-sms-api-behind-the-scenes-dr/featured-img_http-curl-nexmo.png

cURL, HTTPS y la SMS API de Nexmo - Entre bastidores

Publicado el May 4, 2021

Tiempo de lectura: 14 minutos

Enviar un SMS con la API Nexmo es tan fácil como iniciar una solicitud a la URL: https://rest.nexmo.com/sms/json. Pero, ¿te has preguntado alguna vez qué ocurre entre bastidores? Cuando solicitas cosas de Internet, ¿qué hace tu ordenador? ¿Qué hace el servidor?

Estas son las preguntas que pretendemos responder a continuación, así que síguenos si quieres comprobarlo por ti mismo.

Antes de empezar

Antes de empezar necesitarás algunas cosas:

  • El sitio cURL para enviar y recibir datos.

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

Realizar la petición https con cURL

Enviar una https a la SMS API de Nexmo es muy sencillo. Sólo tiene que sustituir las siguientes variables en el siguiente ejemplo, y el mensaje debería estar en camino.

KEY DESCRIPTION
NEXMO_KEY Your Nexmo API key, shown in your account overview.
NEXMO_SECRET Your Nexmo API secret, shown in your account overview.
TO_NUMBER The number you are sending the SMS to in E.164 format. For example 447401234567.
SENDER_ID The number or text shown on a handset when it displays your message. You can set a custom Alphanumeric SENDER_ID to represent your brand better if this feature is supported in your country.
curl "https://rest.nexmo.com/sms/json" \ -d "api_key=NEXMO_KEY" \ -d "api_secret=NEXMO_SECRET" \ -d "to=TO_NUMBER" \ -d "from=SENDER_ID" \ -d "text=A text message sent using the Nexmo SMS API" \ -v --trace-time

Puede invocar curl con opciones de línea de comandos que acompañen a la(s) URL(s). Estas opciones pasan información a curl sobre cómo quieres que se comporte.

La documentación de Nexmo utiliza -d para enviar cadenas de datos en una petición POST a un servidor, y estamos añadiendo -v/--verbose para activar el modo detallado.

Esto último nos permite ver la información añadida que nos da el curl internamente, junto con todas las cabeceras que envía y recibe. También añadimos --trace-time para que cURL anteponga a todas las salidas verbose un temporizador de alta resolución para cuando se imprima la línea.

Ahora, echemos un vistazo a la salida:

00:12:04.170951 * Trying 173.193.199.22... 00:12:04.171716 * TCP_NODELAY set 00:12:04.476802 * Connected to rest.nexmo.com (173.193.199.22) port 443 (#0) 00:12:06.208221 * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 00:12:06.208596 * Server certificate: *.nexmo.com 00:12:06.208889 * Server certificate: DigiCert SHA2 Secure Server CA 00:12:06.209038 * Server certificate: DigiCert Global Root CA 00:12:06.209288 > POST /sms/json HTTP/1.1 00:12:06.209288 > Host: rest.nexmo.com 00:12:06.209288 > User-Agent: curl/7.54.0 00:12:06.209288 > Accept: */* 00:12:06.209288 > Content-Length: 124 00:12:06.209288 > Content-Type: application/x-www-form-urlencoded 00:12:06.209288 > 00:12:06.209560 * upload completely sent off: 124 out of 124 bytes 00:12:06.412178 < HTTP/1.1 200 OK 00:12:06.412243 < Server: nginx 00:12:06.412279 < Date: Tue, 03 Apr 2018 23:12:07 GMT 00:12:06.412314 < Content-Type: application/json 00:12:06.412353 < Transfer-Encoding: chunked 00:12:06.412447 < Connection: keep-alive 00:12:06.412520 < Cache-Control: max-age=1 00:12:06.412629 < X-Frame-Options: deny 00:12:06.412681 < X-XSS-Protection: 1; mode=block; 00:12:06.412732 < Strict-Transport-Security: max-age=31536000; includeSubdomains 00:12:06.412789 < Content-Disposition: attachment; filename="api.txt" 00:12:06.412830 < X-Nexmo-Trace-Id: 9af96afd6c3b3271bf964d15390991f6 00:12:06.412871 < { "message-count": "1", "messages": [{ "to": "TO_NUMBER", "message-id": "0C000000A310D8CA", "status": "0", "remaining-balance": "230.56597167", "message-price": "0.03330000", "network": "23420" }] 00:12:06.413000 * Connection #0 to host rest.nexmo.com left intact }

El desglose

Si eres como yo, y tal vez tienes un "amigo" que solía poseer el commandLineMyNemesis GitHub durante un tiempo, puede que necesites echar un segundo vistazo a esa salida. Vamos a dividirlo en pasos y ver qué hace cada uno de ellos.

Búsqueda DNS

* Trying 173.193.199.22... * TCP_NODELAY set * Connected to rest.nexmo.com (173.193.199.22) port 443 (#0)

El protocolo HTTPS que utilizamos habla TCP (Transmission Control Protocol). Con TCP, cURL debe averiguar primero la dirección IP del host solicitado: Trying 173.193.199.22...y luego conectarse a él: Connected to rest.nexmo.com (173.193.199.22) port 443 (#0). Al hacerlo, realiza un protocolo TCP handshake.
La parte '(#0)indica el número interno que cURL ha asignado a esta conexión.

TCP_NODELAY es set por defecto, que habilita el almacenamiento en búfer de segmentos para que los datos puedan enviarse lo más rápidamente posible. Suele utilizarse para aumentar la utilización de la red.

Conexión TLS

HTTPS son las siglas de "Secure HTTP", lo que significa que la capa de transporte TCP se mejora para ofrecer autenticación, cifrado e integridad de los datos, utilizando TLS (Transport Layer Security).

La conexión TLS comienza con un "apretón de manos", una negociación entre el cliente (cURL ejecutándose en tu PC) y el servidor que resuelve los detalles de cómo van a proceder. El "handshake" determina qué conjunto de cifrado se utilizará, verifica el servidor y garantiza que se establece una conexión segura antes de iniciar la transferencia de datos propiamente dicha.

* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Nos informan de que Nexmo eligió “TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256” de las suites de cifrado que ofrecimos. Esto significa que el ECDHE protocolo elegido, que utilizará el RSA algoritmo de clave pública para verificar las firmas de certificados e intercambiar claves, el AES algoritmo de GCM para cifrar datos, y el algoritmo de SHA256 para verificar el contenido de los mensajes.

Certificados de servidor

* Server certificate: *.nexmo.com * Server certificate: DigiCert SHA2 Secure Server CA * Server certificate: DigiCert Global Root CA

Estar seguro de que se está comunicando con el host correcto es tan importante como tener una conexión segura. Durante el intercambio TLS, cURL obtiene el certificado del servidor remoto y verifica su firma comparándolo con su propio almacén de certificados CA. Esto se hace para asegurar que nos comunicamos con el servidor TLS correcto - por lo tanto, el servidor Nexmo es realmente el servidor Nexmo.

Solicitud POST

POST /sms/json HTTP/1.1 Host: rest.nexmo.com User-Agent: curl/7.54.0 Accept: */* Content-Length: 124 Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 124 out of 124 bytes

Una solicitud HTTP enviada por un cliente comienza con una línea de solicitud: POST /sms/json HTTP/1.1seguida de las cabeceras y, opcionalmente, un cuerpo, separado de las cabeceras por una línea vacía.

Las cabeceras de las peticiones llevan información sobre el servidor con el que estamos hablando, la versión de nuestro software, los tipos de contenido que podemos entender y sobre el contenido del cuerpo de la petición.

Encabezados de respuesta

< HTTP/1.1 200 OK < Server: nginx < Date: Tue, 03 Apr 2018 23:12:07 GMT < Content-Type: application/json < Transfer-Encoding: chunked < Connection: keep-alive < Cache-Control: max-age=1 < X-Frame-Options: deny < X-XSS-Protection: 1; mode=block; < Strict-Transport-Security: max-age=31536000; includeSubdomains < Content-Disposition: attachment; filename="api.txt" < X-Nexmo-Trace-Id: 9af96afd6c3b3271bf964d15390991f6 <

La petición que enviamos recibe la correspondiente respuesta HTTP del servidor. Contiene un conjunto de cabeceras y un cuerpo de respuesta, separados por una línea vacía.

La primera línea muestra un código de estadoen este caso, 200 OKque nos indica que la solicitud se ha realizado correctamente.

Las cabeceras contienen metadatos del servidor Nexmo, diciéndonos que usa nginx como plataforma de servidor web, que está enviando contenido en formato JSON, y que el contenido está fragmentado, por lo que no deberíamos esperar una cabecera Content-Length (como cURL envió en la cabecera de la petición).

La parte Connection: keep-alive nos permite saber que se está utilizando la función keepalive cURL lo hace por defecto, de forma que se envían "tramas ping" de un lado a otro cuando la conexión estaría totalmente inactiva. Ayuda a las conexiones ociosas a detectar interrupciones incluso en ausencia de tráfico y ayuda a los sistemas intermedios a entender que la conexión sigue viva.

También hay algunas cabeceras relacionadas con la seguridad, X-Frame-Options: deny no permite a un navegador renderizar esta URL en un <frame>, <iframe> o <object>. Nexmo utiliza esto para evitar ataques de clickjacking, asegurándose de que su contenido no está incrustado en otros sitios. X-XSS-Protection: 1; mode=block; habilita el filtrado XSS, para que el navegador impida la renderización de la página si se detecta un ataque.

La última línea está vacía, que es el marcador utilizado por el protocolo HTTP para señalar el final de las cabeceras.

Órgano de respuesta

{ "message-count": "1", "messages": [{ "to": "TO_NUMBER", "message-id": "0C000000A310D8CA", "status": "0", "remaining-balance": "230.56597167", "message-price": "0.03330000", "network": "23420" }] * Connection #0 to host rest.nexmo.com left intact }

El cuerpo de la respuesta contiene información sobre el texto que hemos enviado, empezando por el número de mensajes: "message-count": "1"seguido de un "messages": con información detallada sobre cada mensaje. Los elementos de este array son los siguientes: el número al que se envió el mensaje, el ID del mensaje, el estado del mensaje, el saldo restante en la cuenta de Nexmo, el coste del mensaje y el ID de la red del destinatario.

Connection #0 to host rest.nexmo.com left intact nos permite saber que la conexión no se cierra como consecuencia de la transferencia. Aunque, tan pronto como cURL vuelva a la línea de comandos, se cerrará.

Conclusión

A pesar de que tomó menos de 2 segundos para enviar un SMS, hay mucho más allá de lo que parece a primera vista. Con suerte, he logrado arrojar algo de luz sobre el funcionamiento interno, y por ahora usted tiene una mejor comprensión de lo que realmente sucede durante una solicitud HTTPS a la API de Nexmo SMS. Si usted todavía tiene preguntas que quedaron sin respuesta, no dude en ponerse en contacto conmigo en twitter.

¿Y ahora qué?

Si desea profundizar aún más en las tecnologías mencionadas, asegúrese de consultar estos recursos sobre Los primeros milisegundos de una conexión HTTPS, Cabeceras HTTP, HTTP sobre TLS, El Protocolo TLS, Todo cURL y la Nexmo SMS API.

Compartir:

https://a.storyblok.com/f/270183/372x373/36054b72d0/julia-biro.png
Julia BiroDefensor del Desarrollador

Julia está comprometida con la capacitación de los desarrolladores mediante la creación de tutoriales, guías y recursos prácticos. Con experiencia en divulgación y educación, su objetivo es hacer que la tecnología sea más accesible y mejorar la experiencia general de los desarrolladores. A menudo se la puede encontrar en eventos de la comunidad local.