【Node.js】httpsモジュールでサーバーを作成する方法

この記事では『Node.jsに標準で含まれているhttpsモジュール』について、

  • 秘密鍵とデジタル証明書の作成方法
  • Node.jsのhttpsモジュールを用いてサーバーを作成する方法

などを図を用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

Node.jsのhttpsモジュールを用いてサーバーを作成する方法

Node.jsのhttpsモジュールはHTTPSサーバー(Webサーバーとも呼ばれる)を作成する上で必要な機能を提供するモジュールです。httpsモジュールはNode.jsに標準で含まれているモジュールなので、Node.jsがインストールされていれば利用できます。

以下に、httpsモジュールを使ってHTTPSサーバーを作成したサンプルコードを示します(後ほど、以下のサンプルコードについて詳しく説明します)。

サンプルコード

// httpsモジュールの読み込み
const https = require('https');
const fs = require('fs');

// 秘密鍵とデジタル証明書をオプションで指定する
const options = {
  key: fs.readFileSync('./private-key.pem'),
  cert: fs.readFileSync('./server-cert.pem'),
};

// HTTPSサーバーの作成
const server = https.createServer(options, (request, response) => {
  // HTTPSレスポンスのステータス行とメッセージヘッダの指定
  response.writeHead(200, {
    'Content-Type': 'text/html',
  });

  // HTTPSレスポンスのメッセージボディの指定
  const responseMessage = '<h1>Hello, World!</h1>';
  response.end(responseMessage);
});

// HTTPSサーバーを待機状態にする
const port = 8080;
server.listen(port);

ディレクトリ構成

httpsTest
├─server.js        // HTTPサーバーを作成するコードを記述する
├─private-key.pem  // PEM形式の秘密鍵
└─server-cert.pem  // PEM形式の証明書

フォルダ名(httpsTest)やファイル名(server.js)はなんでもOKです。また、秘密鍵(private-key.pem)と証明書(server-cert.pem)の作成方法については後ほど説明します。

ではこれから、Node.jsのhttpsモジュールを使って、HTTPSサーバーを作成してみましょう。手順を以下に示します。

HTTPSサーバーを作成する手順

  • 秘密鍵とデジタル証明書を作成する
  • 秘密鍵とデジタル証明書をオプションで指定する
  • httpsモジュールを読み込む
  • HTTPSサーバーを作成する
  • HTTPSサーバーを待機状態にする
  • 作成したHTTPSサーバーを起動する

あわせて読みたい

以下のリンクでは、Node.jsのhttpモジュールを用いてHTTPサーバーを作成する方法を説明しています。

HTTPSサーバーを作成する際には、秘密鍵とデジタル証明書を作成して、オプションで指定する必要があります(手順1と手順2の作業です)。その他の手順は上記のリンクとほぼ同じです。

秘密鍵とデジタル証明書を作成する

秘密鍵を作成する

まず、openssl genrsaコマンドを実行して、RSA暗号方式の秘密鍵(プライベートキー)を作成します。

openssl genrsa -out private-key.pem 2048

オプションの意味

  • -out filename
    • filenameには出力する秘密鍵のファイル名を指定する。
  • 2028
    • openssl genrsaコマンドのみだと、1024bitの鍵長のRSAの秘密鍵が作成されます。2028というオプションを付けると2028bit の鍵長の秘密鍵を作成することができます。

このコマンドが成功すると、private-key.pemと言う秘密鍵がカレントディレクトリに生成されます。

あわせて読みたい

opensslコマンドを使用するためには、OpenSSLがインストールされている必要があります。

OpenSSLのインストール方法』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

CSR(証明書署名要求)を作成する

openssl reqコマンドを実行して、CSR(証明書署名要求)を作成します。CSRはデジタル証明書を作成する際に使用します。

openssl req -new -key private-key.pem -out server-csr.pem -subj “/C=JP/ST=TestState/L=TestCity/O=TestCompany/OU=TestSection/CN=example.com”

オプションの意味

  • -new
    • 新しくCSR(証明書取得申請書)を生成する
  • -key filename
    • filenameには入力する秘密鍵のファイル名を指定する。
  • -out filename
    • filenameには出力するCSRのファイル名を指定する。
  • -subj
    • 証明書に記載されるサーバ情報を指定する。指定する内容は、/で区切り、以下の書式で指定する。
      • /属性1=値1/属性2=値2/属性3=...
      • 属性と値は以下を指定する。
        • C:2文字の国コード 日本は“JP”
        • ST:都道府県
        • L:市区町村
        • O:組織名
        • OU:部門名
        • CN:サーバの FQDN

-subjオプションを省略した場合は、コマンド実行時に以下のように入力を求められます。

CSRからデジタル証明書を作成する

openssl x509コマンドを実行して、デジタル証明書を作成します。

openssl x509 -in server-csr.pem -out server-cert.pem -req -signkey private-key.pem -days 365

オプションの意味

  • -days 365
    • 有効期限を365日(1年間)に設定しています。

なお、今回CSR(server-csr.pem)と秘密鍵(private-key.pem)に対して自分自身で署名を行って、デジタル証明書を作成しています。自分自身が署名をしたデジタル証明書はオレオレ証明書(自己署名証明書)と呼ばれています。

【補足】秘密鍵とデジタル証明書を一括で作成するコマンド

以下のコマンドを実行すると、秘密鍵とデジタル証明書を一括で作成することができます。

openssl req -subj “/C=JP/ST=TestState/L=TestCity/O=TestCompany/OU=TestSection/CN=example.com” -x509 -nodes -days 365 -newkey rsa:2048 -keyout private-key1.pem -out server-cert1.pem

秘密鍵とデジタル証明書をオプションで指定する

以下のコードでは、先ほど作成した秘密鍵(private-key.pem)とデジタル証明書(server-csr.pem)をオプションで指定しています。

const fs = require('fs');
const options = {
  key: fs.readFileSync('./private-key.pem'),
  cert: fs.readFileSync('./server-cert.pem'),
};

keyプロパティには、PEM形式の秘密鍵(private-key.pem)、certプロパティにはPEM形式のデジタル証明書(server-csr.pem)を指定します。

httpsモジュールを読み込む

以下のコードでは、httpsモジュールを読み込んでいます。

// httpsモジュールの読み込み
const https = require('https');

require('https')httpsモジュールを読み込み、定数httpsに格納しています。

HTTPSサーバーを作成する

以下のコードではHTTPSサーバーを作成しています。

// HTTPSサーバーの作成
const server = https.createServer(options, (request, response) => {
  // HTTPSレスポンスのステータス行とメッセージヘッダの指定
  response.writeHead(200, {
    'Content-Type': 'text/html',
  });

  // HTTPSレスポンスのメッセージボディの指定
  const responseMessage = '<h1>Hello, World!</h1>';
  response.end(responseMessage);
});

先ほど読み込んだhttpsモジュールのcreateServerメソッドを実行すると、HTTPSサーバーを作成することができます。createServerメソッドの引数には、リクエストを受け取った際に行う処理を関数で記述します。関数の第1引数requestと第2引数responseはそれぞれリクエストとレスポンスを示しています。

第1引数requestにはクライアントからのHTTPSリクエストに関する機能を提供するオブジェクトが渡され、第2引数responseにはクライアントへのHTTPSレスポンスに関する機能を提供するオブジェクトが渡されます。

また、作成した秘密鍵(private-key.pem)とデジタル証明書(server-cert.pem)が指定されたoptionオブジェクトをcreateServerメソッドの引数に指定する必要があります。

HTTPSレスポンスを実装する

以下のコードではHTTPSレスポンスを実装しています。

// HTTPSレスポンスのステータス行とメッセージヘッダの指定
response.writeHead(200, {
  'Content-Type': 'text/html',
});

// HTTPSレスポンスのメッセージボディの指定
const responseMessage = '<h1>Hello, World!</h1>';
response.end(responseMessage);

HTTPSレスポンスは以下の3要素で構成されます。

  • ステータス行、レスポンス行
    • 3桁の数字で構成され、リクエストの結果が入る
  • メッセージヘッダ、HTTPSヘッダー、ヘッダーフィールド
    • 送信するデータの情報などの追加情報が入る
  • メッセージボディ、ボディ、メッセージ本体、エンティティボディ
    • リクエストに対する、サーバー応答内容の本文が入る

第2引数のresponseオブジェクトのwriteHeadメソッドの第1引数にはステータス行、第2引数にはメッセージヘッダを指定します。

上記のコードにおいて、ステータス行にはHTTPSリクエストが成功した際に返す「ステータスコード200」を指定しています。また、メッセージヘッダには様々な情報を入れることができますが、今回はデータの種類を伝えるContent-Typeのみを指定しています。

ステータス行の詳細

ステータス行には、HTTPSリクエストが成功したか失敗したかを表すデータ(ステータスコード)を入れます。ステータスコードは以下のように分類されます。

  • 情報レスポンス:100–199
  • 成功レスポンス:200–299
  • リダイレクトメッセージ:300–399
  • クライアントエラーレスポンス:400–499
  • サーバーエラーレスポンス:500–599

メッセージボディは第2引数のresponseオブジェクトのendメソッドの引数にはメッセージボディを指定します。

補足

endメソッドではなく、以下に示すようにwriteメソッドを用いても、メッセージボディを指定することができます。

const responseMessage = '<h1>Hello, World</h1>';
res.write(responseMessage);
res.end();

HTTPSサーバーを待機状態にする

以下のコードではHTTPSサーバーを待機状態にしています(HTTPSサーバーは待機状態でないと通信することができません)。

const port = 8080;
server.listen(port);

createServerメソッドで作成オブジェクト(定数server)には、listenメソッドがあります。listenメソッドを用いると、サーバーを待機状態にすることができます。待機状態にするポート番号はlistenメソッドの引数で指定します。上記のコードではポート8080番を待機状態にしています。

作成したHTTPサーバーを起動する

server.jsが格納されているhttpsServerディレクトリにコンソールで移動し、以下のコマンドを実行すると、サーバーを起動させることができます。

node server.js

作成したHTTPSサーバーにHTTPSリクエストを送るためのURLは以下のようになっています。

Chrome等のWebブラウザの画面上部のアドレスバーに「https://localhost:8080/」を入力し、enterを押します。Webブラウザは証明書の署名が登録されている認証局のものでない場合に「保護されていない通信」と判断されてしまうため、画像のように表示されてしまいます。「詳細設定」をクリックし、「localhost にアクセスする(安全ではありません)」を再度クリックしてアクセスをしてください。

Node.jsのhttpsモジュールを用いてサーバーを作成する方法01

「localhost にアクセスする(安全ではありません)」をクリックすると、以下の画面が表示されます。

Node.jsのhttpsモジュールを用いてサーバーを作成する方法02

https://localhost:8080/」を入力してenterを押すと、作成したHTTPSサーバーにHTTPSリクエストが送られます。HTTPSサーバーはHTTPSレスポンスとして、「Hello, World!」を画面に表示するためのHTMLファイルを返しているため、画面上には「Hello, World!」が表示されています。

なお、URLの左にある「保護されていない通信」→「証明書が無効です」をクリックすると通信に使われた証明書の内容を表示することができます。

Node.jsのhttpsモジュールを用いてサーバーを作成する方法03

HTTPSサーバーを停止するには、コンソールでctrl+cを押します。

本記事のまとめ

この記事では『Node.jsに標準で含まれているhttpsモジュール』について、以下の内容を説明しました。

  • 秘密鍵とデジタル証明書の作成方法
  • Node.jsのhttpsモジュールを用いてサーバーを作成する方法

お読み頂きありがとうございました。