Cookieを使用してシングルページアプリを認証する

シングルページアプリ(SPA)のセキュリティ保護は困難な場合があります。ただし、SPAが次の基準を満たしている場合は、Cookieを使用して認証することで実装を簡素化できます。

  • 独自のバックエンドを使用してクライアントに提供される。

  • バックエンドと同じドメインを持つ。

  • バックエンドへの認証を必要とするAPI呼び出しを行う。

このアプローチの説明と、Node.jsを使用したサンプル実装を次に示します。

仕組み

以下の手順では、トークンを取得して使用する方法を示します。このアプローチでは、従来のProof Key for Code Exchangeを使用した認可コードフローの代わりに、フォームPOSTを使用した暗黙フローが使用されます。これは、アクセスを要求しているのが独自のリソースである場合、フォームPOST応答モードの方がログインを実装する簡単な方法であるためです。

Authenticate Single-Page Apps Using Cookies How it Works part 1 diagram

  1. ユーザーがブラウザを使用して保護されたルートにアクセスするか、認証手順の開始を必要とする何らかのアクションを実行します(ログインボタンをクリックするなど)

  2. ブラウザクライアントは、ユーザーの操作内容に応じて、バックエンドの/loginルートまたは保護されたルートにリダイレクトします

  3. バックエンドは、認可サーバーの/authorizeエンドポイントへの要求を作成し、ブラウザクライアントをそこにリダイレクトします

  4. ユーザーは、認可サーバーが提示する任意の方法を使用して認証するように求められます

  5. 認可サーバーは、トークンをURLエンコードされたフォームPOSTとしてリダイレクトURIにPOSTします。バックエンドは、本文データを解析してこれらのトークンを取得できます。

この時点で、ユーザーは認証され、バックエンドは必要なトークンを持っています。これで、クライアントでこの状態を表すCookieを作成できます。次に、クライアントブラウザは、SPAを提供するルートにリダイレクトされ、認証Cookieも受け取ります。

今後、AJAX呼び出しを使用してAPI呼び出しが行われると、このCookieはクライアントとバックエンドの間で交換されます。要求ごとに、バックエンドはCookieがまだ有効かどうかを確認し、有効であれば要求続行を許可します。

Authenticate Single-Page Apps Using Cookies How it Works part 2 diagram

無効または欠落しているCookie

このアプローチを実装する場合、認証Cookieが無効または欠落している場合の処理が必要になります。クライアントからバックエンドへのAPI呼び出しはバックグラウンドで行われるため、クライアントは、ユーザーが再認証する必要があることを示すサーバーからの応答を処理する必要があります。

次のサンプルアプリケーションでは、API呼び出しの結果が302リダイレクトである場合にユーザーに再認証を求めるという単純な方法でこのケースが処理されます。302が発生するのは、Cookieの検証に失敗すると、サーバーが認可サーバーの認可エンドポイントにリダイレクトしようとし、この応答をクライアントに送信するためです。

サンプルアプリケーションでは、Node.jsとExpressを使用して、上記の概念を説明します。

前提条件

  • この手順を実行するには、最新バージョンのNodeがインストールされていることを確認してください。

  • Nodeがインストールされたら、ソースコードをダウンロードまたは複製し、ターミナルウィンドウ内でプロジェクトフォルダーを開きます。

    // Clone the tutorial respository using SSH
    git clone git@github.com:auth0-blog/spa-cookie-demo
    // ... or if you use HTTPS:
    git clone https://github.com/auth0-blog/spa-cookie-demo.git
    // Move into the project directory
    cd spa-cookie-demo

    Was this helpful?

    /

  • masterブランチは、認証が追加される前のアプリケーションの状態を表します。アプリケーションの最終バージョンを参照する場合は、with-oidcブランチをチェックアウトします。 git checkout with-oidc

Node.jsアプリを初期化する

ターミナルウィンドウからnpm installを実行して、アプリケーションの依存関係をインストールします。アプリケーションを実行するには、npm run devを使用します。これにより、Expressサーバーが起動します。アプリケーションを表示するには、ブラウザでhttp://localhost:3000にアクセスしてください。

開発サーバーはnodemonを使用します。nodemonはファイルの変更を検出すると自動的に再起動します。

アプリケーションを探索する

アプリケーションをhttp://localhost:3000で開いた状態で、[Call API(APIの呼び出し)]ボタンをクリックします。画面にメッセージが表示されます。

SPA Authentication with Cookies Explore the Application screen

ログインせずにAPI呼び出しを実行できました。API呼び出しを実行する前に、ユーザーの認証を要求するミドルウェアを追加してこれを修正しましょう。

環境をセットアップする

アプリケーションが認証を使用して動作するには、express-openid-connectにいくつかの環境変数が必要です。このアプリケーションでは、これらの変数は.envファイルで指定できます。プロジェクトディレクトリのルートに.envファイルを作成し、次の内容を入力します。

ISSUER_BASE_URL=<YOUR OIDC URL>
CLIENT_ID=<YOUR OIDC CLIENT ID>
BASE_URL=http://localhost:3000
APP_SESSION_SECRET=<YOUR SECRET VALUE>

Was this helpful?

/

Auth0でアプリをセットアップする

  1. [Dashboard]>[Applications(アプリケーション)]>[Applications(アプリケーション)]に移動して、[Create Application(アプリケーションの作成)]をクリックします。

  2. 新しいアプリケーションに名前を付け、[Regular Web Applications(通常のWebアプリケーション)]を選択して、[Create(作成)]をクリックします。

  3. 新しいアプリの[Settings(設定)]で、http:/localhost:3000/callback[Allowed Callback URLs(許可されているコールバックURL)]に追加します。

  4. http:/localhost:3000[Allowed Logout URLs(許可されているログアウトURL)]に追加します。

  5. [Save Changes(変更を保存)]をクリックします。

  6. [Dashboard]>[Authentication(認証)]>[Social(ソーシャル)]に移動し、ソーシャル接続をいくつかセットアップします。[Connections(接続)]タブの[Application(アプリケーション)]オプションで、アプリに対してそれらを有効にします。例では、ユーザー名/パスワードデータベース、Facebook、Google、およびXを使用します。

  7. [Settings(設定)]画面で、上部のドメインとクライアントID設定をメモします。

  8. アプリケーションの一部として構成する必要がある値が2つあります。.envファイルを再度開き、次の値を設定します。

    ISSUER_BASE_URL={yourDomain}
    CLIENT_ID={yourClientId}
    BASE_URL=http://localhost:3000
    APP_SESSION_SECRET=<YOUR SECRET VALUE>

    Was this helpful?

    /

アプリを実行する

  1. サーバーと環境の構成が完了したら、アプリケーションが開いているブラウザーウィンドウを見つけます。ブラウザーを閉じてサーバーを停止した場合は、ターミナルから次のコマンドを実行してアプリケーションを再起動します。 npm run dev

  2. ブラウザーでhttp://localhost:3000を開きます。ユーザーインターフェイス上のアプリは同じように見えますが、今回は、[Call API(APIの呼び出し)]ボタンをクリックするとユーザーがログインしていないという警告が表示されます。また、APIへの呼び出しが拒否されたため、以前のように「Hello, World」メッセージが表示されることもありません。

  3. [Log in now(今すぐログイン)]をクリックしてログインします。認証されると、アプリに戻り、新しいログイン状態を反映した更新されたUIが表示されます。[Call API(APIの呼び出し)]ボタンをもう一度押すと、サーバーへのAPI呼び出しが実行され、今度は成功します。

  4. ページ上部の[Profile(プロファイル)]リンクをクリックすると、IDトークンから取得したユーザー情報が表示されます。

もっと詳しく