https://a.storyblok.com/f/270183/83374/00e8a569d2/featured-img_http-curl-nexmo.png

cURL、HTTPSとNexmo SMS API - 舞台裏

最終更新日 May 4, 2021

所要時間:9 分

Nexmo APIを使ってSMSを送信するのは、https://rest.nexmo.com/sms/json というURLにリクエストを送るだけと簡単です。しかし、その裏で何が起こっているのか不思議に思ったことはありませんか?インターネットから何かをリクエストするとき、あなたのコンピューターは何をしているのでしょうか?サーバーは何をしているのでしょうか?

これらの質問に対する答えを以下に記すので、自分の目で確かめたい人はフォローしてほしい。

始める前に

始める前にいくつか必要なものがある:

  • その cURLコマンドラインツールでデータを送受信する。

cURLでhttpsリクエストを行う

Nexmo SMS APIへの httpsNexmo SMS APIへのリクエストは簡単です。以下の例で、以下の変数を置き換えるだけで、メッセージが送信されます。

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

curlは コマンドラインオプションを付けることができます。これらのオプションは、どのように動作させたいかという情報をcurlに渡します。

Nexmoドキュメントでは -dを追加しています。 -v/--verboseを追加しています。

後者は、curlが送受信するすべてのヘッダーと一緒に、curl内部から追加された情報を見ることができる。また --trace-timeを追加し、cURLがすべての冗長出力の前に、その行が出力されるときの高解像度のタイマーを付けるようにしました。

さて、出力を見てみよう:

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 }

ブレイクダウン

もしあなたが私のようなもので、しばらくの間 commandLineMyNemesisGitHubのハンドルネームをしばらくの間所有していた「友人」がいるような場合は、この出力をもう一度見てみる必要があるかもしれません。ステップに分解して、それぞれが何をしているのか見てみましょう。

DNSルックアップ

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

私たちが使用したHTTPSプロトコルは、TCP(Transmission Control Protocol)を話します。TCPでは、cURLはまず要求されたホストのIPアドレスを見つけなければならない: Trying 173.193.199.22...それから接続する: Connected to rest.nexmo.com (173.193.199.22) port 443 (#0).そうすることで TCPプロトコルのハンドシェイク.
この'(#0)'の部分は、cURLがこの接続にどの内部番号を与えたかを示します。

TCP_NODELAYである。 setデフォルトでは、セグメントバッファリングを有効にし、データをできるだけ早く送信できるようにします。通常、ネットワークの利用率を高めるために使用される。

TLS接続

HTTPSは "Secure HTTP "の略で、TLS(Transport Layer Security)を使って、認証、暗号化、データの完全性を提供するためにTCPトランスポート層を強化することを意味する。

TLS接続は、クライアント(PC上で実行されているcURL)とサーバー間のネゴシエーションである "ハンドシェイク "から始まり、どのように処理を進めるかの詳細を整理する。ハンドシェイクでは、使用する暗号スイートを決定し、サーバーを検証し、実際のデータ転送を開始する前に安全な接続が確立されていることを確認します。

* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

ネクスモは我々が提供した暗号スイートから “TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256”を選んだとのことです。これは ECDHEプロトコルが選ばれたことを意味する。 RSA証明書の署名のVerifyと鍵の交換に公開鍵アルゴリズムを使う。 AESアルゴリズム GCMでデータを暗号化し SHA256でメッセージの内容を検証する。

サーバー証明書

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

正しいホストと通信していることを確認することは、安全な接続と同様に重要です。TLSハンドシェイクの間、cURLはリモート・サーバー証明書を取得し、自身のCA証明書ストアと照合してその署名を検証します。これは正しいTLSサーバーと通信していることを確認するために行われます。つまり、Nexmoサーバーは確かにNexmoサーバーなのです。

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

クライアントが送信するHTTPリクエストは、リクエスト行で始まる: POST /sms/json HTTP/1.1その後にヘッダが続き、オプションでボディが空行でヘッダと区切られる。

リクエストヘッダは、私たちが会話しているサーバー、私たちのソフトウェアのバージョン、私たちが理解できるコンテンツタイプ、リクエストボディの内容に関する情報を伝えます。

レスポンス・ヘッダ

< 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 <

私たちが送ったリクエストは、サーバーから対応するHTTPレスポンスを受け取っている。ヘッダーのセットとレスポンス・ボディを含み、空行で区切られている。

最初の行は ステータスコードこの場合は 200 OKこれはリクエストが成功したことを知らせる。

ヘッダーにはNexmoサーバーからのメタデータが含まれており、ウェブサーバープラットフォームとしてnginxを使用していること、JSONフォーマットでコンテンツを送り返すこと、コンテンツがチャンクされていることを伝えている。 Content-Lengthヘッダを期待すべきではありません(cURLがリクエストヘッダで送信したようなものです)。

この Connection: keep-alive部分は、TCPの keepalivecURLはデフォルトでこの機能を使用し、接続がまったくアイドル状態でない場合でも、"pingフレーム "が送受信されるようにしています。これは、トラフィックがない状態でもアイドル接続が切断を検出するのを助け、中間システムが接続がまだ生きていることを理解するのを助けます。

セキュリティ関連のヘッダもいくつかあります、 X-Frame-Options: denyは、ブラウザがこのURLを<frame>、<iframe>、<object>内にレンダリングすることを許可しません。Nexmoはこのヘッダを使用して、コンテンツが他のサイトに埋め込まれないようにすることで、クリックジャッキング攻撃を回避しています。 X-XSS-Protection: 1; mode=block;はXSSフィルタリングを有効にし、攻撃が検出された場合にブラウザがページのレンダリングを防ぐようにします。

最後の行は空で、これはHTTPプロトコルがヘッダーの終わりを知らせるために使うマーカーである。

回答本文

{ "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 }

レスポンス・ボディには、メッセージの数から始まる、送信したテキストに関する情報が含まれる: "message-count": "1"で始まり "messages":オブジェクトの配列が続きます。この配列の要素は次のとおりです:メッセージの送信先番号、メッセージのID、メッセージのステータス、Nexmoアカウントの残金、メッセージのコスト、受信者のネットワークのID。

Connection #0 to host rest.nexmo.com left intactを使用すると、転送の結果として接続がクローズされないことを知ることができます。しかし、cURLがコマンドラインに戻り次第、接続は閉じられます。

結論

SMSを送信するのに2秒もかからなかったとはいえ、最初は目に見える以上のことが起こっています。NexmoのSMS APIへのHTTPSリクエストで実際に何が起こっているのか、ご理解いただけたと思います。もしまだ疑問が残っているようでしたら、お気軽に ツイッター.

次はどうする?

これらの技術についてさらに深く知りたい方は、以下のリソースをご覧ください。 HTTPS接続の最初の数ミリ秒, HTTPヘッダー, HTTPオーバーTLS, TLSプロトコル, cURLのすべてそして Nexmo SMS API.

シェア:

https://a.storyblok.com/f/270183/372x373/36054b72d0/julia-biro.png
Julia Biroデベロッパー・アドボケイト

Juliaは、チュートリアル、ガイド、実用的なリソースを作成することで、仲間の開発者に力を与えることに尽力しています。アウトリーチと教育のバックグラウンドを持つ彼女は、テクノロジーをより身近なものにし、開発者の経験全体を向上させることを目指しています。地域のコミュニティイベントでもよく見かける。