Node.js API 実装 (SPAs + API)
ステップ 1. API エンドポイントを定義する
package.json ファイルを作成する
npm init を実行します。これにより、package.json ファイルが作成されます。
デフォルト設定のままでも、必要に応じて変更してもかまいません。
このサンプルの package.json は次のようになります。
依存関係をインストールする
- express: このモジュールは、Express web application framework を追加します。
- cors: このモジュールは、CORS を有効にするためのサポートを追加します。これは、Web ブラウザー内の別のドメインで実行されるシングルページアプリケーションから API が呼び出されるため、必要です。
- jwks-rsa: このライブラリは、JWKS (JSON Web Key Set) エンドポイントから RSA 署名鍵を取得します。
expressJwtSecretを使用すると、 ヘッダー内のkidに基づいて、適切な署名鍵をexpress-jwtに提供するシークレットプロバイダーを生成できます。詳しくは、node-jwks-rsa GitHub repository を参照してください。 - express-jwt: このモジュールを使用すると、Node.js アプリケーションで JWT を使って HTTP リクエストを認証できます。JWT を扱いやすくするための複数の関数も提供されています。詳しくは、express-jwt GitHub repository を参照してください。
- body-parser: これは Node.js のリクエストボディを解析する middleware です。受信したリクエストストリームのボディ全体を抽出し、扱いやすい形で
req.bodyとして公開します。詳しい情報といくつかの代替手段については、body-parser GitHub repository を参照してください。
エンドポイントを実装する
server.js ファイルを作成します。コードでは次のことを行います。
- 依存関係をインストールします。
- エンドポイントを実装します。
- API サーバーを起動します。
node serverで API サーバーを起動し、localhost:8080/timesheets に HTTP POST リクエストを送信します。This is the POST /timesheets endpoint というメッセージを含む JSON レスポンスが返されるはずです。
これでエンドポイントは用意できましたが、現時点では誰でも呼び出せてしまいます。これをどのように解決するかは、次の段落で確認してください。
ステップ 2. API エンドポイントを保護する
jwt 関数と、シークレットを取得するための jwks-rsa を使用します。これらのライブラリは次の処理を行います。
express-jwtはトークンをデコードし、リクエスト、ヘッダー、ペイロードをjwksRsa.expressJwtSecretに渡します。- 次に
jwks-rsaは JWKS エンドポイントからすべての署名鍵をダウンロードし、そのいずれかが JWT のヘッダー内のkidと一致するかを確認します。受信したkidと一致する署名鍵がない場合は、エラーがスローされます。一致するものがあれば、適切な署名鍵をexpress-jwtに渡します。 - その後
express-jwtは独自のロジックを続行し、トークンの署名、有効期限、audience、issuerを検証します。
- を検証するミドルウェア関数を作成します。
- ルートでミドルウェアを使用できるようにします。
localhost:8080/timesheets に HTTP POST を送信すると、Missing or invalid token というエラーメッセージが返されるはずです (リクエストでアクセストークンを送信していないため、これは想定どおりです) 。
動作するケースもテストするには、次の手順を実行します。
- アクセストークンを取得します。取得方法の詳細については、Get an Access Token を参照してください。
- リクエストに
Authorizationヘッダーを追加し、その値にBearer ACCESS_TOKENを指定して API を呼び出します (ACCESS_TOKENは最初の手順で取得したトークンの値です) 。
ステップ 3. アプリケーションの権限を確認する
scope) を持っているかどうかを確認する機能を実装に追加します。特に、トークンに正しいスコープ (batch:upload) が含まれていることを確認します。
これを行うには、express-jwt-authz Node.js パッケージを使用するため、プロジェクトに追加してください。
jwtAuthz(...) の呼び出しを追加するだけです。
追加の依存関係を 1 つ追加します。express-jwt-authz ライブラリは express-jwt と組み合わせて使用され、JWT を検証したうえで、目的のエンドポイントを呼び出すために必要な適切な権限があることを確認します。詳細については、express-jwt-authz GitHub repository を参照してください。
以下はサンプル実装です (簡潔にするため、一部のコードは省略しています) :
403 のエラーメッセージ Forbidden が返されるはずです。これを確認するには、API からこのスコープを削除してください。
ステップ 4. ユーザーの識別情報を特定する
express-jwt ミドルウェアは、JWT に含まれる情報を req.auth にも設定します。ユーザーを一意に識別するために sub クレームを使用する場合は、req.auth.sub をそのまま使用できます。
ただし、このタイムシートアプリケーションでは、一意の識別子としてユーザーのメールアドレスを使用します。
まず、ユーザーのメールアドレスをアクセストークンに追加する Rule を作成する必要があります。Dashboard の Rules section に移動し、Create Rule ボタンをクリックします。
Rule には、たとえば Add email to Access Token のようなわかりやすい名前を付け、次のコードを使用します。
namespace は、クレームに一意の名前を付け、標準の OIDC クレーム名と競合しないようにするために使用されます。ただし、Auth0 は名前空間付きと名前空間なしの両方のカスタムクレームをサポートしています。カスタムクレームの詳細については、Create Custom Claims を参照してください。
次に、API 内で req.auth からクレームの値を取得し、それをタイムシートのエントリに関連付ける一意のユーザー ID として使用できます。