> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.generaltranslation.app/llms.txt
> Use this file to discover all available pages before exploring further.

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

> バックエンドサーバーを使用して、Cookieを使ってシングルページアプリ（SPA）を認証する方法について説明します。

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        let processedChildren = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          processedChildren = processedChildren.replace(new RegExp(key, "g"), value);
        }
        setProcessedChildren(processedChildren);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
      {processedChildren}
    </CodeBlock>;
};

export const codeExample = `ISSUER_BASE_URL="{yourDomain}"
CLIENT_ID="{yourClientId}"
BASE_URL="http://localhost:3000"
APP_SESSION_SECRET="<YOUR SECRET VALUE>"`;

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

* 独自のバックエンドを使用してクライアントに提供される。
* バックエンドと同じドメインを持つ。
* バックエンドへの認証を必要とするAPI呼び出しを行う。

このアプローチの説明と、[Node.js](https://nodejs.org/en/)を使用したサンプル実装を次に示します。

<div id="how-it-works">
  ## 仕組み
</div>

以下の手順では、トークンを取得して使用する方法を示します。このアプローチでは、従来の[Proof Key for Code Exchangeを使用した認可コードフロー](/docs/ja-JP/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce)の代わりに、[フォームPOSTを使用した暗黙フロー](/docs/ja-JP/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post)が使用されます。これは、アクセスを要求しているのが独自のリソースである場合、フォームPOST応答モードの方がログインを実装する簡単な方法であるためです。

<Frame>
  <img src="https://mintcdn.com/generaltranslationinc/pd2Xk6Hu-Ldfi_VV/docs/images/ja-jp/cdy7uua7fh8z/7suPpG6SuHuCOFHeFmE21T/5267823b7316b17b35b5bdea60ddc03d/2023-09-22_13-21-34__ja-JP_.png?fit=max&auto=format&n=pd2Xk6Hu-Ldfi_VV&q=85&s=e4873add7082347d16097028b1b072dc" alt="Authenticate Single-Page Apps Using Cookies How it Works part 1 diagram" width="430" height="379" data-path="docs/images/ja-jp/cdy7uua7fh8z/7suPpG6SuHuCOFHeFmE21T/5267823b7316b17b35b5bdea60ddc03d/2023-09-22_13-21-34__ja-JP_.png" />
</Frame>

1. ユーザーがブラウザを使用して保護されたルートにアクセスするか、認証手順の開始を必要とする何らかのアクションを実行します（ログインボタンをクリックするなど）
2. ブラウザクライアントは、ユーザーの操作内容に応じて、バックエンドの`/login`ルートまたは保護されたルートにリダイレクトします
3. バックエンドは、認可サーバーの`/authorize`エンドポイントへの要求を作成し、ブラウザクライアントをそこにリダイレクトします
4. ユーザーは、認可サーバーが提示する任意の方法を使用して認証するように求められます
5. 認可サーバーは、トークンをURLエンコードされたフォームPOSTとしてリダイレクトURIにPOSTします。バックエンドは、本文データを解析してこれらのトークンを取得できます。

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

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

<Frame>
  <img src="https://mintcdn.com/generaltranslationinc/UCtxRPLKKGiAgiWv/docs/images/ja-jp/cdy7uua7fh8z/6SCp9KwQkwJV7L26TOuxIO/518d563a979195af59e0c5638b49eadb/2023-09-22_13-21-50.png?fit=max&auto=format&n=UCtxRPLKKGiAgiWv&q=85&s=619180b421d55b764ebf9fac4ac0951c" alt="Authenticate Single-Page Apps Using Cookies How it Works part 2 diagram" width="747" height="346" data-path="docs/images/ja-jp/cdy7uua7fh8z/6SCp9KwQkwJV7L26TOuxIO/518d563a979195af59e0c5638b49eadb/2023-09-22_13-21-50.png" />
</Frame>

<div id="invalid-or-missing-cookies">
  ### 無効または欠落しているCookie
</div>

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

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

<div id="example">
  ## 例
</div>

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

<div id="prerequisites">
  ### 前提条件
</div>

* この手順を実行するには、[最新バージョンのNode](https://nodejs.org/en/download/)がインストールされていることを確認してください。

* Nodeがインストールされたら、[ソースコードをダウンロードまたは複製](https://github.com/auth0-blog/spa-cookie-demo/)し、ターミナルウィンドウ内でプロジェクトフォルダーを開きます。

  ```shell lines theme={null}
  # 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
  ```

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

<div id="initialize-the-nodejs-app">
  ### Node.jsアプリを初期化する
</div>

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

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

<div id="explore-the-application">
  ### アプリケーションを探索する
</div>

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

<Frame>
  <img src="https://mintcdn.com/generaltranslationinc/pd2Xk6Hu-Ldfi_VV/docs/images/ja-jp/cdy7uua7fh8z/7JhdgzFLig2xcDle7ziiGp/c1db6272d20d4a291ba90a6968460109/image3.png?fit=max&auto=format&n=pd2Xk6Hu-Ldfi_VV&q=85&s=9543d1f4459fdebec56f78bd3df477d3" alt="SPA Authentication with Cookies Explore the Application screen" width="937" height="677" data-path="docs/images/ja-jp/cdy7uua7fh8z/7JhdgzFLig2xcDle7ziiGp/c1db6272d20d4a291ba90a6968460109/image3.png" />
</Frame>

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

<div id="set-up-environment">
  ### 環境をセットアップする
</div>

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

```bash lines theme={null}
ISSUER_BASE_URL=<YOUR OIDC URL>
CLIENT_ID=<YOUR OIDC CLIENT ID>
BASE_URL=http://localhost:3000
APP_SESSION_SECRET=<YOUR SECRET VALUE>
```

<div id="set-up-app-in-auth0">
  ### Auth0でアプリをセットアップする
</div>

1. [［Dashboard］>［Applications（アプリケーション）］>［Applications（アプリケーション）］](https://manage.auth0.com/#/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（ソーシャル）］](https://manage.auth0.com/#/connections/social)に移動し、ソーシャル接続をいくつかセットアップします。**［Connections（接続）］** タブの **［Application（アプリケーション）］** オプションで、アプリに対してそれらを有効にします。例では、ユーザー名/パスワードデータベース、Facebook、Google、およびXを使用します。
7. **［Settings（設定）］** 画面で、上部のドメインとクライアントID設定をメモします。
8. アプリケーションの一部として構成する必要がある値が2つあります。`.env`ファイルを再度開き、次の値を設定します。

   <AuthCodeBlock children={codeExample} language="shell" lines />

<div id="run-the-app">
  ### アプリを実行する
</div>

1. サーバーと環境の構成が完了したら、アプリケーションが開いているブラウザーウィンドウを見つけます。ブラウザーを閉じてサーバーを停止した場合は、ターミナルから次のコマンドを実行してアプリケーションを再起動します。
   `npm run dev`
2. ブラウザーで[http://localhost:3000](http://localhost:3000)を開きます。ユーザーインターフェイス上のアプリは同じように見えますが、今回は、**［Call API（APIの呼び出し）］** ボタンをクリックするとユーザーがログインしていないという警告が表示されます。また、APIへの呼び出しが拒否されたため、以前のように「Hello, World」メッセージが表示されることもありません。
3. **［Log in now（今すぐログイン）］** をクリックしてログインします。認証されると、アプリに戻り、新しいログイン状態を反映した更新されたUIが表示されます。**［Call API（APIの呼び出し）］** ボタンをもう一度押すと、サーバーへのAPI呼び出しが実行され、今度は成功します。
4. ページ上部の **［Profile（プロファイル）］** リンクをクリックすると、IDトークンから取得したユーザー情報が表示されます。

<div id="learn-more">
  ## もっと詳しく
</div>

* [フォームPOSTを使った暗黙フロー](/docs/ja-JP/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post)
* [セキュリティ保護](/docs/ja-JP/ja-jp/secure)
* [sameSiteクッキー属性の変更](/docs/ja-JP/ja-jp/manage-users/cookies/samesite-cookie-attribute-changes)
