【とっても簡単】開発中のNode.js ExpressでのSSLのhttps設定
Node.jsのExpressを利用したアプリケーションの開発時にhttpsを利用しないといけない制約が出た場合のSSLの設定方法について説明を行っています。
動作確認は、macOSのBig Surで行っています。Node.jsが事前にOSにインスールされていることが前提となっています。
Expressではhttpsを利用するための機能は備わっていますが、httpsを利用するために秘密鍵と自己証明者が必要となります。秘密鍵と証明書を作成するためopensslコマンドを実行しますが、opensslコマンドはmacOSの中に入っています。
目次
Expressの環境構築
httpsサーバとして設定を行う前にExpressを使ってhttpサーバを構築します。
任意の名前のフォルダを作成(ここではmyapp)を作成し、フォルダ内でnpm init -yコマンドを実行しpackage.jsonファイルを作成します。
% mkdir myapp
% cd myapp
% npm init -y
Expressのインストールを行います。
% npm install express
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN myapp@1.0.0 No description
npm WARN myapp@1.0.0 No repository field.
+ express@4.17.1
added 50 packages from 37 contributors and audited 50 packages in 1.878s
found 0 vulnerabilities
ファイルの更新を監視するためにnodemonをインストールします。
% npm install nodemon
myappフォルダにindex.jsファイルを作成して以下を記述します。
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Listening on port ${port}!`))
index.jsファイル作成後Expressを起動します。nodemonを利用しています。
% npx nodemon index.js
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`
Example app listening on port 3000!
index.jsファイルで指定したポート3000にブラウザからアクセスし、ブラウザ上にHello World!が表示されることを確認します。表示されればExpsssの環境構築は完了です。
https設定
httpsを設定していない場合にhttps://localhost:3000にブラウザからアクセスすると以下の画面が表示されます。このエラーが表示されるのはhttps通信にWEBサーバが対応していないためです。
秘密鍵と自己署名証明書の作成
opensslコマンドを利用して秘密鍵(privatekey.pem)と自己署名証明書(cert.pem)を作成します。対話形式でContry Nameなど聞かれますが開発用で一時的にhttpsを利用するために設定を行うのでいずれかの質問の一つを入力してください。後はEnterを押してください。ここではContry Nameに”JP”を入力しています。
% openssl req -x509 -newkey rsa:2048 -keyout privatekey.pem -out cert.pem -nodes -days 365
Generating a 2048 bit RSA private key
.....................................................................................+++
...................+++
writing new private key to 'privatekey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:JP
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:
Email Address []:
実行すると実行フォルダにprivatekey.pemとcert.pemファイルが作成されます。
作成した秘密鍵と自己署名証明書をindex.jsファイルで指定します。秘密鍵と自己署名証明書はindex.jsファイルと同じフォルダに保存しているので./privatekey.pemを設定しています。パスには気をつけてください。
const express = require('express')
const app = express()
const port = 3000
const fs = require('fs');
const server = require('https').createServer({
key: fs.readFileSync('./privatekey.pem'),
cert: fs.readFileSync('./cert.pem'),
}, app)
app.get('/', (req, res) => res.send('Hello World!'))
server.listen(port, () => console.log(`Listening on port ${port}!`))
Chromeブラウザからのアクセス(NET::ERR_CERT_INVALID)
設定後にhttps://localhost:3000にアクセスすると先ほどとは異なり警告画面が表示されます。証明書を一時的に作成しているだけなので、認証情報が正しくないためにこのエラー(NET::ERR_CERT_INVALID)が表示されています。
ページを表示させるためには、詳細設定のボタンをクリックしてください。
この画面でthisisunsafeと入力してください。URLの入力欄には証明書が正しくないため”保護されていない通信”と表示されますがブラウザ上にはhttpで接続した時と同じ内容が表示されます。
また保護されていない通信をクリックすると以下の画面が表示されます。証明書が無効であることがわかります。
自己証明ルート証明書であることがわかり、先ほどのopensslの実行時に入力したCountry NameのJPやコマンドのオプションに指定したX.509などを確認することができます。
証明書が有効の場合は以下のように証明書(有効)が表示されます。
一度”thisisunsafe”を入力すると次の接続で警告が表示されなくなった場合は保護されていない通信をクリックして、”警告を再度有効にする”をクリックしてください。
Firefoxブラウザからのアクセス
ChromeブラウザではなくFirefoxブラウザを開発に利用している人もいるかと思います。Firefoxブラウザで接続するとChromeと同様に警告が表示されます。Advancedボタンをクリックしてください。
証明書が信頼できないために警告が表示されています。開発用で問題がないことがわかっているのでAccept the Risk and Continue(リスクを理解した上で続ける)ボタンをクリックします。
http通信で接続した時と同じ内容が表示されます。
以上でExpressにおけるhttpsの設定方法の手順は完了です。開発しているExpressを利用したアプリケーションでhttpsが必要な場合はぜひ試してみてください。