TL;DR:本書では、オープンソース Web アプリので継続的配置パイプラインを構築する方法について学んでいきます。デモの目的で、パイプラインを自動化する Now.sh、GitHub、Travis CI を使用します。ただし、他のプログラミング言語(Python、Java、 .NET Core など)やツール(BitBucket、AWS、 CircleCI など)を使用するという戦略でいきます。

「オープンソース Web アプリので継続的配置パイプラインを構築する方法について学んでいきます。」

継続的配置の概要

継続的配置(CD として広く知られる)はソフトウェアのリリースを自動化することに関係する現代ソフトウェアエンジニアリングのアプローチです。ソフトウェアを生産に押し出す通常の手動方式を使う代わりに、継続的配置はパイプラインを使用するこのプロセスを簡単にし、自動化することを狙います。継続的配置では、ソースコードに更新することはすべてのテストに合格すれば、運用サーバーも更新することでもあります。継続的配置は継続的インテグレーションや継続的デリバリーに間違えられることがよくあります。この概念の感覚をつかむために、まずほかの2つの概念を区別しましょう。

継続的インテグレーション(CIでは、新しいコードがチェックインされたら、ビルドが生成され、テストされます。その狙いはソフトウェア全体が中断されないように、新しいコードすべてをテストすることです。このため、プッシュされた更新すべての書き込みテストが必須になります。CI の重要性は特にひとつのチームに複数の開発者がいるときに、安定したコードベースを常に確実にすることです。このため、自動化テストが失敗すると、バグがより早く発見されます。

継続的デリバリーは継続的インテグレーションの一歩先を行きます。テストの後、リリースプロセスも自動化されます。その狙いはリリース可能なビルドを生成することです(生産へ移動できるだけの安定性があるビルドなど)これは、リリースを準備する煩わしさの削減に役立ちます。継続的デリバリーでは、正規のリリースがあるので、フィードバックもより早くなります。

継続的デリバリーと継続的配置の間の大きな違いはリリースが行われるその方法です。一方は手動であるのに対して、他方は自動化されています。継続的デリバリーでは、ソフトウェアは常に、手動で生産に押し出される状態にあります。それに対して、継続的配置はソフトウェアが安定して作動するバージョンが即座に生産にプッシュされます。継続的配置は継続的デリバリーが必要ですが、その反対は当てはまりません。

これらすべてでは、コードが存在するレポジトリと、コードをチェックするレポジトリをモニターする継続的インテグレーションサーバーが必要です。そのサーバーがコードの中の更新に気づくと、パイプラインをトリガーします。このコンテキストのパイプラインはプロジェクトで実行されるコマンドやタスクを含むスクリプト/ファイルです。一般的に、継続的インテグレーションを構成するときは、それに平行してパイプラインをセットアップします。継続的インテグレーションサーバーの一部には Travis CIJenkinsTeamCityなどがあります。

本書では、継続的インテグレーションサーバーが実際に継続的配置を示すために GitHub レポジトリと一緒にセットアップする方法を学んでいきます。継続的配置の重大な理由は、大きなチームのより良い統合、より早くかつより簡単なリリース、より早いフィードバック、開発生産性の全体的な向上などがあります。

継続的配置向け オープンソース Web アプリを準備する

本章では、Node.js を使ってシンプルな Hello World アプリを構築していきます。そのようなものとして、まず、 次に進む前にお使いのマシンに Node.js がインストールされているか確認します。

node --version

上記のコマンドを実行すると、端末は v9.11.1 と同様のものを印刷します。node が見つかりません」というメッセージが表示されたら、この リンクに従って Node.js と NPM をインストールします。

Node.js Web アプリをスキャフォールディングする

ここで、お使いにマシンに Node.js がインストールできたので、Node.js アプリケーションの構造をセットアップします。簡単にセットアップするために、新しいディレクトリで npm init -y を実行します(これはプロジェクトルートになります)。このコマンドによって package.json ファイルが生成され、それには Node.js アプリの詳細が含まれます。この package.json ファイルには使用されている依存関係の名前に関係するアプリの基本情報が含まれています。

プロジェクトと package.json ファイルを作成するには、端末で次のコマンドを実行します。

# create the project root
mkdir node-cd

# move into the project root
cd node-cd

# start it as an NPM project
npm init -y

最後のコマンドを実行すると、NPM が package.json ファイルを生成します。ここで、アプリのディレクトリを開いたら、次を含む package.json ファイルが表示されます。

{
  "name": "node-cd",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Node.js Web アプリの依存関係をインストールする

package.json ファイルを作成した後、プロジェクトを構築するために必要な依存関係をインストールする必要があります。本書では、expressbody-parser の2つの依存関係だけが必要です。次のコマンドを実行して、これらすべての依存関係を一度にインストールします。

npm install express body-parser --save

このインストールが完了すると、node_modules フォルダーが表示されます。さらに、package.json ファイルにはインストールされた依存関係とそのバージョンが含まれています。

Node.js で Web ページを作る

アプリのセットアップ中に NPM がアプリのエントリ ポイントとして index.js ファイルを宣言します。では、このファイルを作成します。プロジェクト ルートで、次のコマンドを実行してファイルを作成します。

touch index.js

次に、HTML ファイルを作成する必要があります。通常、ビューのディレクトリを作成することが推奨されます。そのようなものとして、プロジェクトルートの次のコマンドを実行して、ディレクトリや HTML ファイルを作成します。

# ビューのディレクトリを作成します
`mkdir`` pages`

# 最初のビューを作成します
`touch pages/index.html`

ここで Node.js Web アプリを HTML ファイルで使用できるようにするため、index.js ファイルを開き、次のように設定します。

// 依存関係をインポートします
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');

// Express を初期化します
const app = express();

// ルートのエンドポイント
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname + '/pages/index.html'));
});

// Node.js Web アプリを実行するポートを選択します
const port = 5000;

// それから選択されたポートをモニターします
app.listen(port, () => console.log(`Server is running on port ${port}`));

このスニペットにはこのアプリに必要なすべてのサーバーロジックが含まれています。ご覧のように、宣言されているのはただひとつのエンドポイントです(index.html ページを読み込むもの)また、上記のコードで定義されているように、このアプリはポート 5000 で実行します。

ここで、コンテンツの一部を index.html ファイルに追加するには、このファイルを開き、次のコードを挿入します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title Page</title>
    <!-- Bootstrap CSS -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.3/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
</head>
<body>
  <h1 class="text-center">Hello World</h1>  
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

これは、コンテンツデリバリネットワーク(CDN)で参照される ブートストラップ(見事な Web アプリを構築するのに役立つライブラリ)jQuery (ブートストラップで必要な JavaScript __ライブラリ) の基本的な HTML コードです。Web ページはテキストを見出しにするために h1 タグにある Hello World テキストを含みます。ここで、このコマンドでサーバーを実行します。

node index.js

http://localhost:5000 に移動しますと、次のようなものが表示されます。

Hello world screenshot

これだけです!本書の目的には、現在のプロジェクトで十分です。では、プロジェクトをバージョン管理システムに提出する必要があります。

GitHub およびオープンソース Web アプリ

本書の始めで、作動中の継続的配置を実証するレポジトリの必要性について説明しました。この場合のレポジトリは単にソースコードが格納されている場所です。そのようなものとして、プロジェクトのソースコードをリモート(オンライン)リポジトリに格納する必要があります。

Git は現在で回っているバージョン管理システムの中で最も人気が高く、最も高度なものです。よって、Git レポジトリをホストできるサービスを選択してください。現在、たくさんのホストが出回っていますが、その中でも最も人気が高い GitHub を使用します。GitHub は Web サービスで、Git リポジトリをホストします。実際はこれ以上のものを提供してくれますが、その詳細については GitHub __の機能についてはこちらをご覧ください。

GitHub アカウントを作成する

GitHub のアカウントをお持ちでない方は、Web __サイトでアカウントを作成してください。アカウントをすでにお持ちの方は、ご自分のプロファイルにログインしてください。アカウントを作成するには、固有のユーザー名、メールアドレス、任意のパスワードが必要です。

Creating a GitHub account - Github.com signup form

登録が終了したら、メールアドレスを通してアカウントを確認し、フルアクセスを取得します。

GitHub 101:アカウントと新規レポジトリを作成する

GitHub は公開レポジトリ(オープンソースのプロジェクトなど)には無料で、本書の場合にぴったりです。新しいレポジトリを作成するには、プロファイルを開き、[+]ボタンをクリックし、新しいレポジトリを選択します。プロファイルは次のように表示されます。

GitHub profile view and creating a new repository

新しいレポジトリのオプションをクリックした後、次のようなフォームが表示されます。

Creating a new GitHub repository

そのフォームにレポジトリの名前(node-js-cd-pipeline)、詳細(継続的配置など)を記入してから、リポジトリの作成ボタンをクリックします。GitHub がレポジトリを作成したら、リダイレクトされます。そこで、リポジトリの URLhttps://github.com/KingIdee/node-js-cd-pipeline.git のような URL)をコピーできるようになります。この後使用しますので、これをクリップボードにコピーしてください。

注:以前すでに _SSH キーで GitHub アカウントを構成していたら、それをコピーして別の URL フォーマットを使用します。これはgit@github.com:KingIdee/node-js-cd-pipeline.git のようなフォーマットです。

オープンソース Web アプリを GitHub にプッシュする

Node.js Web アプリをセットアップしてその GitHub レポジトリを作成したら、ソースコードをオンラインにプッシュする用意ができましたので、プロジェクトのルートから次のコマンドを実行します。

git init

注:gitコマンドを実行するには Git CLI(コマンド ライン インターフェイス)をインストールする必要があります。

このコマンドは .git フォルダを作成してプロジェクトディレクトリ(ほとんどのオペレーティングシステムでこのディレクトリはデフォルトで非表示です)の Git を初期化します。Git を初期化したら、リモートでの GitHub レポジトリをセットアップする必要があります。

git remote add origin REPO_URL

必ず、以前にコピーしたリポジトリ URL と REPO_URL とを置き換えます。

プロジェクトをリモートリポジトリにプッシュするとき、特定のファイルを無視する必要があることがあります。このプロジェクト(とほとんどの Node.js プロジェクト)の場合、node_modules ディレクトリを無視する必要があります。よって、.gitignore ファイルを次のようにディレクトリに作成します。

touch .gitignore

それから、そのファイルを開き、次の行をペーストします。

/node_modules

次に、プロジェクトに行った変更をコミットし、リモートレポジトリにプッシュします。これは、次のコマンドを実行して行います。

# 変更したファイルを追加します
git add -A

# それらを Git にコミットします
git commit -m "first commit"

# それらを GitHub にプッシュします
git push -u origin master

最初のコマンド(git add)は Git への変更が影響されるすべてのファイルに追加されますが、.gitignore ファイルに明示的に記載されているものは例外です。それから、2つめのコマンド(git commit)はどのような変化があったかを指摘するメッセージが追加/変更ファイルに追加され、ローカルの Git レポジトリにそれらを格納します。最後に、git push コマンドはプロジェクトに加えられたローカルでの変更をリモートのレポジトリ(この場合 GitHub)にプッシュし、リモートでの変更を追跡するローカルプロジェクトをセットアップします。

すべてに問題がなければ、作成したリポジトリにアクセスすると、プロジェクトのソースコードがオンラインで見えるようになります。

Pushing local changes to the GitHub remote repository

Now.sh アプリとオープンソースアプリ

Now はサービスとしてのプラットフォーム(PaaS)で、プロジェクトがクラウドで簡単に配置できるようになります。Now を使って Node.js アプリケーションが簡単に配置できるようになりますが、他の言語(Python、Java など)で開発されたアプリも簡単に配置できますが、この場合は Dockerfile が必要です。

Now は開発者が簡単に継続的配置をできるようにすることを狙いとしています。当然のことながら、Web サイトの構築を Node.js で配置するにはサーバー構成や管理の十分な知識のほかに、端末を自由に使いこなす必要があります。Now を使ってアプリのロジックにより焦点を合わせることができるので、配置について心配が減ります。

Now の素晴らしい機能には次などがあります。

  • 無料の固有 URL:配置されるあらゆる URL には、通常、<appname>-<random string>.now.sh(例:helloworld-hddnhdvhsd.now.sh)のようなフォームで生成される固有な URL がある。.
  • プロセス ログ:配置されるアプリのコマンドを実行するポイントからスクリーンでログインしてサーバーを開始するポイントまでのあらゆるプロセスが、ダッシュボードに表示されている配置インスタンスのリンクをクリックすると表示される。
  • SSL 証明書管理 - Let's Encrypt をご利用になりますと、SSL での配置が無料になる。

さらに素晴らしいことに、Now は1銭も支払わずに、軽量のオープンソースアプリケーションをインフラストラクチャで配置できるようになります。この場合のコードはプロジェクトに関心がある人誰もに対して公開されています。今回はオープンソースのアプリを開発しているので、これは問題にはなりません。また、(データベースに接続する資格情報などの)環境変数はソースコードの一部ではありませんから、一般には共有されません。

Now.sh アカウントを作成する

Now.sh アカウントを作成するには、Now の新規登録ページで利用可能な方法のひとつを選択します(電子メールまたは GitHub アカウントを通してなど)。電子メールを通して登録する場合、マジックリンクでメッセージを受信しますので、そのリンクをクリックしてアカウントを確認します。その後、登録に使用したブラウザのタプが Now のダッシュボードで再度読み込まれます。

そのほかに、GitHub で登録 オプションを選択すると、認証メールがメールアドレスに送信されます。

Eメールを確認した後、Now へのログインができるようになります。新規ユーザーの場合、ルグインした後のダッシュボードは次のように表示されます。

Signing up for a Now.sh account

新規トークンを取得する

登録プロセスが完了して、ログインしたら、右上にあるプロファイルの画像をクリックしてから、Eメールアドレスをクリックします設定オプションの下に表示されます)。.その後、Now はアカウント設定を表示し、プロファイル画像の下にトークンへのリンクが表示されます。それをクリックします。

この次のスクリーンに、承認されているアプリというセクションと、新規トークンを作ることができる入力フィールドが表示されます。このフィールドで、継続的配置のような説明的な名前を挿入し、入力を押します。その後、 Now が新規トークンを生成します。

差し当たり、このページは開いたままにしてください。間もなく、このトークンをコピーすることになりますので。

継続的配置向けの Travis CI を構成する

Travis CI は継続的配置サーバーで、オープンソースのプロジェクトに使用できます。必要であれば、プライベートのプロジェクトにも使用できますが、この場合、その他の Web サイトを使用しなければなりません。上記で説明したように、継続的インテグレーションサーバーはレポジトリの変更をモニターするために使用され、事前に構成されたプロセスが見つかればトリガーします。

Travis CI と特に、GitHub で利用可能なプロジェクトだけをサポートします。これらプロジェクトは .travis.yml と呼ばれるパイプラインファイルをレポジトリのルートディレクトリに追加して構成されます。

Travis アカウントを作成する

次に進むには、Travis CI で登録する必要があります。Travis CI は GitHub だけの登録が必要です。すでに GitHub アカウントをお持ちなので、その Web サイトを開き、登録します。

GitHub オープンソースのプロジェクト向けに Travis CI を構成する

登録が完了したら、ご自分のプロファイルに公開リポジトリのリストが表示されます。そこでは、リポジトリが表示され、その隣にあるチェックボックスボタンをクリックして Travis CI が更新できるようにします。

Activating the GitHub repository on Travis CI

オープンソース Web アプリで Travis を構成する

Travis CI をアクティブ化した後、プロジェクトに戻り、.travis.yml と呼ばれるファイルを作成し、次のコードをそれにペーストします。

language: node_js
node_js:
- node
cache:
  directories:
  - node_modules
before_deploy:
  - npm install now --no-save
  - now rm node-cd --token $NOW_TOKEN --yes || true
deploy:
- provider: script
  # そのアプリケーションを now.sh に配置します
  script: now --public --token $NOW_TOKEN
  skip_cleanup: true
  on:
    master: true

このファイルを慎重に分析するのであれば、次が分かります。

  • language プロパティはプロジェクトで使用する主なテクノロジーが何かを定義する(Node.js など)。
  • Before_deploy プロパティは配置段階の前に実行されるコマンドを適切に特定する。この場合、インストールされた Now CLI が必要で、以前のすべての配置を削除することを Travis CI に伝える(now rm node-cd)。この最後のコマンドは Now の無料レベルを使っているのでが必要である。
  • Deploy セクションはプロジェクトを配置するために使用するレシピ(コマンド)を定義する。この場合、master ブランチに送信される変更を配置する now を使用することを Travis に伝える(master: true)。

注:これがなぜ、now rm node-cd コマンドに対して || true が必要かと疑問に思われている方への説明です。初めてコードをプッシュする場合、Now でのアプリはありませんから、このコマンドは失敗します。|| true を追加しなければ、Travis CI は now rm コマンドが失敗するのでビルド プロセスを停止します。

これを念頭に置いて、package.json ファイルを開き、次のように scripts セクションを再定義します。

{
  "scripts": {
    "start": "node index.js"
  }
}

Now トークンを Travis CI に与える

セキュリティは、秘密キーが関係するかもしれないので、アプリケーションを配置するときには重要です。例えば、この場合、Now トークンが秘密キーです。環境変数としてこのキーを Travis CI に設定することが実行のアプローチに見えるかもしれません。残念ながら、これは完全に安全ではありません。キーを適切に安全にするには、Travis CLI(コマンド ライン インターフェイス)を使用する必要があります。これを使用するには、Ruby と RubyGems をマシンにインストールする必要があります。

これらをまだインストールしていないのであれば、このドキュメンテーションに従ってしてください。

その後、gem を使用して Travis CLI をインストールします。

gem install travis

Travis CLI をローカル環境にインストールしたら、これを使ってプロジェクトのルートディレクトリにある次のコマンドを実行して Now トークンを暗号化できます。

travis encrypt NOW_TOKEN=YOUR_TOKEN --add

上記のコマンドにある YOUR_TOKENNow ダッシュボードで利用可能なトークン(このページは開いたままのはずですね?)を置き換えるのを忘れないでください。

このコマンドは Now トークンを暗号化し、そのエンコードしたバージョンを env セクションの下にある .travis.yml に追加します。このコマンドが成功すると、以下に表示のように .travis.yml ファイルに構成の一部が表示されます。

env:
  global:
    secure: DZC4XpjVPoPl4oXKPD2QATP4++vpPUXllQW0XZjUnSp4S/U9zQamciEMPjvwot324CC/nWm8eL5EyY5WIEyhvhbWwtl85GIYJJeSVhJbkOcwX9Z8Z95aE+9ajI0IMNgE9xS0f8jHYqUOSGTDz0aagGrl8ZgA/qI7qL7QZKLgX07e3nh5Zgyjtrgvyukhchtyiuhoetryuiozb4EoUUc8LJAZJPXBcok/qAmuxPQe6vZt5OTmhNPeL0efdRt861dql45A2qHKOGREYm3Ma0aV1IuqeCLrmoJkT5u7oGd+pG+OWh7LlgA1bjFbTufT/2YiGqCKDNLwbsX8OzBqOlu0Snm8Rb32Yr6VJIw/ulVweg+ZRsEIdNaY=

Travis CI(このプロパティを読み取り、解読できる唯一のパーティー)はこのキーを使って配置スクリプトを実行するときに NOW_TOKEN 環境変数に設定します。それから、最後に、プロジェクトを Now(now --public --token $NOW_TOKEN コマンドを通して)に配置するこの変数を使います。

Now での名前を定義する

最後に、Now と Travis を一緒に設定しなければならなことはプロジェクトルートに now.json と呼ばれるファイルを作成し、次のコンテンツをそれに加えます。

{
  "name": "node-cd"
}

このファイルはプロジェクトの name を Now に伝えるので Now がそれを配置するときに固有 URL を定義するのに役立ちます。

作動中の継続的配置パイプライン

配置パイプラインをテストするには、ファイルを追加(または変更/削除)して、コミットし、リモートの GitHub レポジトリにプッシュするだけです。このレポジトリで Travis CI を有効にしたので、GitHub は新しい変更について Travis CI に警告し、その配置プロセスが始まります。

最初の変更をプッシュする

まだその変更をコミットしたり .``travis.ymlpackage.jsonnow.json に送信したりしていないので、変更を GitHub にプッシュするためにプロジェクトのルートディレクトリから次のコマンドを発行できます。

git add -A

git commit -m "継続的転回パイプラインをTravis CI や GitHub で構成した"

git push

変更を GitHub レポジトリにプッシュすると、Travis CI は配置プロセスをトリガーし、そのビルド プロセスを引継ぎます。そのプロセスが進むと、Travis ダッシュボード上にログが見えてきます。

Travis CI logs while deploying your open-source web app

注:現在のジョブを見るには、ログイン中に、Travis CI のメインページに移動してください。そこから実行中のジョブがすべて見えるはずです。

Travis CI がビルドプロセスを完了したら、Now ダッシュボードに移動して現在の配置インスタンスを見ることができます。そこでは、新しい配置へのリンクがイベントセクションの下に表示されます。

Now.sh dashboard events after the first deployment

それをクリックすると、新しいブラウザタブにオープンソースの Node.js アプリが開かれます。

2つめの変更をプッシュする

ここで、継続的配置パイプラインが適切に機能することを確認するために、pages/index.html ファイルにさらに変更を加えて GitHub にプッシュします。たとえば、このファイルを開いて、h1 要素とこれを置き換えます。

<h1 class="text-center">
  I've just finished configuring a Continuous Deployment pipeline for my open-source, Node.js web app.
</h1>

それから、端末から次のコマンドを発行します。

git add -A

git commit -m "index.html ファイルの新規メッセージ"

git push

最後のコマンドの後、GitHub は新しい変更について Travis CI に通知し、新規の配置プロセスが始まります。数分後、Travis CI がそのビルドを終え、Now を使ってオープンソースの Node.js Web アプリの新規バージョンを配置します。

それを見るには、Now ダッシュボードに戻り、アイコンをクリックして Now が定義した最新の URL を開きます。

The second deployment of the open-source web app

「オープンソース Web アプリの継続的配置パイプラインを構築しました。」

補足:Node.js アプリケーションを Auth0 でセキュアする

Node.js アプリケーションを Auth0 でセキュアにすることは簡単で、たくさんの素晴らしい機能を提供します。Auth0 を使うと、数行のコード行を書くだけで、強固なID __管理ソリューションシングル サインオンソーシャル ID プロバイダー(Facebook、GitHub、Twitter など)のサポート、および_エンタープライズ ID プロバイダー(Active Directory、LDAP、SAML、カスタムなど)のサポートを得ることができます。

以下のセクションでは、Express で書かれた Node.js API をセキュアにする Auth0 を使用する方法を学んでいきます。

Express API を作る

Node.js API を定義することから始めましょう。Express および Node.js を使って、2 つのシンプルなステップでこれが可能になります。1 つめのステップでは NPM を使って 3 つの依存関係のnpm i express body-parser cors をインストールします。

注:ゼロから始めるのであれば、まず、NPM プロジェクトのnpm init -y を初期化しなければなりません。.これによって NPM が現在のディレクトリ内に新しいプロジェクトを作成します。そのようなものとして、このコマンドを実行する前に、新しいプロジェクト要に新しいディレクトリを作成し、それに移動しなければなりません。

ふたつめは、次のコードで(これを index.js を呼びます) Node.js スクリプトを作成します。

// 依存関係をインポートします
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');

// Express を構成します
const app = express();
app.use(bodyParser.json());
app.use(cors());

// Contact 配列を定義します
const contacts = [
  { name: 'Bruno Krebs', phone: '+555133334444' },
  { name: 'John Doe', phone: '+191843243223' }
];

// Contacts 配列を操作するエンドポイントを定義します
app.get('/contacts', (req, res) => res.send(contacts));
app.post('/contacts', (req, res) => {
    contacts.push(req.body);
    res.send();
});

// Express を始めます
app.listen(3000, () => console.log('Example app listening on port 3000!'));

上記のコードは Express アプリケーションを作成し、次の 2 つのミドルウェアのJSON リクエストを分析する body-parser、とアプリがいずれの発生元からリクエストを受け入れるというシグナルを出す cors を追加します。アプリは 2 つのエンドポイントを Express に登録し、POST リクエストと GET リクエストを処理します。両方のエンドポイントはある種のメモリ内データベースとして contacts 配列を使います。

ここで、Node index をプロジェクトルートに発行してアプリケーションを実行し、リクエストをそれに送信してテストできます。例えば、cURL を使うと、 curl localhost:3000/contacts を発行して GET リクエストを送信できます。このコマンドはアイテムを contacts 配列に出力します。

API を Auth0 で登録する

このアプリケーションを作成した後、それを安全にすることに中心に実行していけます。このアプリを表す API を Auth0 に登録することから始めましょう。これをするには、管理ダッシュボードの API セクション(必要であれば無料アカウントを作ることができます)に移動し、「API の作成」をクリックします。表示されたダイアログ上で、この API を 「Contacts API」 と名付け(名前はあまり重要ではありません)、https://contacts.blog-samples.com/ (後ほど、この値を使用します)としてそれを識別します。

Express を Auth0 でセキュアする

ここまでで、API を Auth0 アカウントに登録したので、Express API を Auth0 でセキュアしましょう。3 つの依存関係をnpm i express-jwt jwks-rsa の NPM でインストールすることから始めましょう。それから、auth0.js と呼ばれるファイルを作り、これらの依存関係を使用しましょう。

const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');
module.exports = jwt({

  // ヘッダーの KID をベースにして、署名するキーおよび
  // JWKS エンドポイントによって提供された署名するキーをフェッチします。
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
  }),

  // 対象ユーザーと発行元を検証します。
  audience: process.env.AUTH0_AUDIENCE,
  issuer: `https://${process.env.AUTH0_DOMAIN}/`,
  algorithms: ['RS256']
});

このスクリプトの目標は、リクエストが、信頼に値するパーティ、この場合は Auth0 が発行した access_token があることを保証する Express __ミドルウェア をエクスポートすることです。このスクリプトは次の 2 つの環境変数を検索することが予測されます。

  • AUTH0_AUDIENCE : API の識別子(https://contacts.mycompany.com/
  • AUTH0_DOMAIN : Auth0 でのドメイン(この場合 bk-samples.auth0.com

これらの変数は後ほど、設定しますが、ドメイン変数が、ミドルウェアがどのようにして署名するキーを検索するかを定義することを理解することが重要です。

このミドルウェアを作成した後で、index.js ファイルを更新してインポートし、以下のようにそれを使用します。

// ... その他はステートメントが必要です ...
const auth0 = require('./auth0');

// ... アプリの定義と Contact 配列 ...

// 両方のエンドポイントを定義します
app.get('/contacts', auth0(), (req, res) => res.send(contacts));
app.post('/contacts', auth0(), (req, res) => {
  contacts.push(req.body);
  res.send();
});

// ... app.listen ...

この場合では、前のエンドポイントの定義は、有効なアクセストークンを送信するリクエストを適用する新規ミドルウエアを使用するために置き換えられました。

ここで、アプリケーションの実行は以下のような環境変数を設定する必要があるので、多少異なります。

export AUTH0_DOMAIN=blog-samples.auth0.com
export AUTH0_AUDIENCE="https://contacts.blog-samples.com/"
node index

API を実行した後、適切に保護されているかを見るためにそれをテストできます。では、端末を開き、次のコマンドを発行しましょう。

curl localhost:3000/contacts

すべてが設定されると、サーバーから「認証トークンが見つかりません」という返答を受けます。

ここで、再度、エンドポイントと対話するために、Auth0 からアクセストークンを取得しなければなりません。これをするには複数の方法があり、使用する戦略は開発するクライアントアプリケーションのタイプによって異なります。たとえば、シングルページ アプリケーション(SPA)を開発するのであれば、Implicit Grant**(インプリシットグラント) と呼ばれるものを使用します。モバイル アプリケーションを開発するのであれば、PKCE を使用する Authorization Code Grant Flow**(認証コードグラントフロー) を使用します。Auth0 で利用可能なフローは他にもありますが、.今回のようなシンプルなテストには、Auth0 ダッシュボードを使って取得しますので、

Auth0 ダッシュボードの API セクション に戻り、前に作成した API をクリックし、この API のテストセクションをクリックします。そこに、トークンのコピーと呼ばれるボタンがあります。このボタンをクリックして、ダッシュボードからアクセストークンをコピーしましょう。

Copying a test token from the Auth0 dashboard.

このトークンをコピーしたら、端子を開き、次のコマンドを発行します。

# トークンで変数を作成します
ACCESS_TOKEN=<OUR_ACCESS_TOKEN>

# この変数を使って Contacts をフェッチします
curl -H 'Authorization: Bearer '$ACCESS_TOKEN` http://localhost:3000/contacts/

注:<OUR_ACCESS_TOKEN> をダッシュボードからコピーしたトークンに置き換える必要があります。

API に送信するリクエストのアクセストークンを使用しているので、再度、Contact のリストを取得します。

このようにして Node.js バックエンド API を安全にします。簡単ですよね?

まとめ

本書では、継続的配置という、最新のソフトウェア開発におけるホットな用語のひとつを取扱いました。Git、継続的インテグレーションサーバー、および継続的配置におけるそれぞれの役割も簡単に学んできました。特に、オープンソース Web アプリ用の継続的配置パイプラインを構成する GitHub、Travis CI、Now.sh といったツールを使用しました。すごいですね?

この知識を使って、継続的インテグレーションをもっと複雑なプロジェクトに適用することができます。CI サーバーや Git をホストする新しい Web サービスなど、本書で使ったものと同様のツールに挑戦してみるのもいいでしょう。

皆さんが構築されたものを見る日を楽しみにしています。頑張りましょう!