メインコンテンツへスキップ
このセクションでは、このシナリオ向けの API を実装する方法を見ていきます。
簡潔にするため、この実装では認証と認可のみに絞ります。サンプルで示すとおり、入力するタイムシートエントリはハードコードされており、API でそのタイムシートエントリが永続化されることはありません。代わりに、その情報の一部をそのまま返すだけです。

API エンドポイントを定義する

まず、API のエンドポイントを定義する必要があります。

API エンドポイントとは

API エンドポイントは、オブジェクトを表す一意の URL です。このオブジェクトとやり取りするには、アプリケーションからその URL を指定する必要があります。たとえば、注文または顧客を返す API がある場合は、/orders/customers という 2 つのエンドポイントを設定できます。アプリケーションは異なる HTTP メソッドを使用してこれらのエンドポイントとやり取りします。たとえば、POST /orders で新しい注文を作成し、GET /orders で 1 件以上の注文データを取得できます。
この実装では、定義するエンドポイントは 2 つだけです。1 つは従業員のすべてのタイムシートの一覧を取得するためのもので、もう 1 つは従業員が新しいタイムシートエントリを作成できるようにするものです。 /timesheets エンドポイントへの HTTP GET リクエストにより、ユーザーは自分のタイムシートを取得できます。また、/timesheets エンドポイントへの HTTP POST リクエストにより、ユーザーは新しいタイムシートを追加できます。 実装は Node.js で確認してください。

エンドポイントを保護する

API がヘッダーにベアラー を含むリクエストを受け取った場合、最初に行うべきことはそのトークンを検証することです。これには一連の手順があり、そのいずれかに失敗した場合は、呼び出し元アプリケーションに Missing or invalid token エラーメッセージを返して、リクエストを拒否する必要があります。 API が実行すべき検証は次のとおりです。
  • の形式が正しいことを確認する
  • 署名を確認する
  • 標準クレームを検証する
JWT.io では、JWT の解析、署名の検証、クレームの検証など、この作業の大半を実行できるライブラリの一覧を提供しています。
検証プロセスの一環として、アプリケーションの権限 (スコープ) も確認する必要がありますが、これについてはこのドキュメントの次の段落で個別に説明します。 アクセストークンの検証の詳細については、アクセストークンを検証する を参照してください。 実装例については Node.js を参照してください。

アプリケーションの権限を確認する

ここまでで、JWT が有効であることを検証できました。最後に、保護されたリソースへのアクセスに必要な権限をアプリケーションが持っていることを確認します。 そのため、API はデコードされた JWT のスコープを確認する必要があります。このクレームはペイロードの一部で、スペース区切りの文字列リストです。 実装については Node.js を参照してください。

ユーザーの識別方法

どちらのエンドポイント (タイムシート一覧の取得と新しいタイムシートの追加) でも、ユーザーの識別が必要です。 タイムシート一覧を取得する場合は、リクエストを行ったユーザーに属するタイムシートだけを返すためです。新しいタイムシートを追加する場合は、そのタイムシートをリクエストを行ったユーザーに関連付けるためです。 標準的な JWT クレームの 1 つに、クレームの対象となる主体を識別する sub クレームがあります。Implicit Grant フローでは、このクレームにユーザーの識別情報が含まれます。これは Auth0 ユーザーの一意の識別子です。これを使うと、外部システム内の任意の情報を特定のユーザーに関連付けることができます。 また、カスタムクレームを使用して、ユーザーの別の属性 (メールアドレスなど) をアクセストークンに追加し、それを使ってユーザーを一意に識別することもできます。 実装については Node.js を参照してください。

SPA を実装する

このセクションでは、このシナリオで SPA を実装する方法を見ていきます。

ユーザーを認可する

ユーザーを認可するには、auth0.js ライブラリ を使用します。Auth0 アプリケーションの新しいインスタンスは、次のように初期化できます。 次の設定値を渡す必要があります。
  • clientID: Auth0 の の値です。Dashboard の Application の Settings から取得できます。
  • domain: Auth0 のドメインの値です。Dashboard の Application の Settings から取得できます。
  • responseType: 使用する認証フローを指定します。Implicit Flow を使用する SPA の場合は、token id_token に設定する必要があります。token の部分は、フローが URL フラグメントでアクセストークンを返すようにし、id_token の部分は、フローが も返すようにします。
  • : API Identifier の値です。Dashboard の API の Settings から取得できます。
  • redirectUri: ユーザーの認証後に Auth0 がリダイレクトする先の URL です。
  • scope: IDトークン とアクセストークンで返される情報を決定する スコープ です。openid profile スコープを指定すると、IDトークン にすべてのユーザープロファイル情報が返されます。また、API を呼び出すために必要なスコープ (この場合は read:timesheets create:timesheets) もリクエストする必要があります。これにより、アクセストークンにこれらのスコープが含まれることが保証されます。
認証フローを開始するには、authorize() メソッドを呼び出します。
auth0.authorize();
認証後、Auth0 は、Auth0 アプリケーションの新しいインスタンスの設定時に指定した redirectUri にリダイレクトします。この時点で、URL のハッシュフラグメントを解析して Auth0 の認証レスポンス結果を取得する parseHash() メソッドを呼び出す必要があります。 parseHash が返す authResult オブジェクトの内容は、使用した認証パラメーターによって異なります。次の項目が含まれる場合があります。
  • idToken: ユーザープロファイル情報を含む IDトークン JWT
  • accessToken: 対象者 で指定した API のアクセストークン。
  • expiresIn: アクセストークンの有効期限 (秒単位) を表す文字列。
トークンの保存場所を決定してください。シングルページアプリにバックエンドサーバーがある場合は、トークンを Authorization Code Flow または Authorization Code Flow with Proof Key for Code Exchange (PKCE) を使用してサーバー側で処理する必要があります。 対応するバックエンドサーバーがないシングルページアプリ (SPA) の場合、SPA はログイン時に新しいトークンをリクエストし、永続化せずにメモリ内に保存する必要があります。API 呼び出しを行う際は、SPA はそのメモリ内のトークンのコピーを使用します。 SPA でセッションを処理する方法の例については、JavaScript Single-Page App Quickstart の Handle Authentication Tokens セクションを参照してください。 実装例は Angular 2 を参照してください

ユーザープロファイルを取得する

トークンから情報を取得する

このセクションでは、アクセストークンと /userinfo エンドポイント を使用してユーザー情報を取得する方法を説明します。この API 呼び出しを避けるには、代わりに IDトークン を ライブラリを使用して デコードすることもできます (先に必ず検証してください) 。追加のユーザー情報が必要な場合は、バックエンドから Management API を使用することを検討してください。
client.userInfo メソッドは、返された authResult.accessToken を渡して呼び出すことで、ユーザーのプロファイル情報を取得できます。これにより /userinfo エンドポイント にリクエストが送信され、ユーザー情報を含む user オブジェクトが返されます。以下の例のような内容です。
{
    "email_verified": "false",
    "email": "test@example.com",
    "clientID": "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH",
    "updated_at": "2017-02-07T20:50:33.563Z",
    "name": "tester9@example.com",
    "picture": "https://gravatar.com/avatar/example.png",
    "user_id": "auth0|123456789012345678901234",
    "nickname": "tester9",
    "created_at": "2017-01-20T20:06:05.008Z",
    "sub": "auth0|123456789012345678901234"
}
userInfo 関数の呼び出し時に渡されるコールバック関数では、これらのプロパティのいずれにもアクセスできます。
const accessToken = authResult.accessToken;

auth0.client.userInfo(accessToken, (err, profile) => {
  if (profile) {
    // ユーザーのニックネームとプロフィール画像を取得する
    var nickname = profile.nickname;
    var picture = profile.picture;
  }
});
実装例については Angular 2 を参照してください。

スコープに基づいて UI 要素を条件付きで表示する

ユーザーのscopeに応じて、特定の UI 要素を表示または非表示にできます。ユーザーに発行されたスコープを確認するには、認可プロセスで最初にリクエストしたスコープを保存しておく必要があります。ユーザーが認可されると、scopeauthResultでも返されます。 authResult内のscopeが空の場合は、リクエストしたすべてのスコープが付与されたことを意味します。authResult内のscopeが空でない場合は、付与されたスコープのセットが異なることを意味するため、authResult.scopeに含まれる値を使用してください。 実装例については Angular 2 を参照してください。

API を呼び出す

API の保護されたリソースにアクセスするには、認証済みユーザーのアクセストークンを、その API に送信するリクエストに含める必要があります。これを行うには、Bearer スキームを使用して Authorization ヘッダーにアクセストークンを設定します。 実装例については Angular 2 を参照してください。

アクセストークンを更新する

セキュリティ対策として、ユーザーのアクセストークンの有効期間は短く設定しておくことを推奨します。 で API を作成すると、デフォルトの有効期間は 7200 秒 (2 時間) ですが、API ごとに設定できます。 有効期限が切れると、アクセストークンは API へのアクセスに使用できなくなります。再度アクセスするには、新しいアクセストークンを取得する必要があります。 新しいアクセストークンを取得するには、最初のアクセストークンを取得したときと同じ認証フローをもう一度実行します。ただし SPA では、認証フローを再度完了するためにユーザーを現在の作業からリダイレクトしたくない場合があるため、これは理想的ではありません。 このような場合は、サイレント認証 を利用できます。サイレント認証では、Auth0 はリダイレクトのみを返し、ログインページは表示しない認証フローを実行できます。ただし、この方法を使用するには、ユーザーが事前に シングルサインオン (SSO) でログインしている必要があります。 実装例は Angular 2 を参照してください。