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

# Hono アプリケーションにログイン機能を追加する

> このクイックスタートでは、Auth0 認証を使用して Hono アプリケーションを保護する方法を説明します。手順に従って、Hono アプリにログイン、ログアウト、保護されたルートを追加します。

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<HowToSchema />

<Callout icon="pencil" color="#FFC107" iconType="solid">
  このクイックスタートは現在**ベータ版**です。ぜひフィードバックをお寄せください。
</Callout>

<Note>
  **前提条件:**

  * **Node.js** 20 LTS 以降
  * **npm** 10 以降、**yarn** 1.22 以降、または **pnpm** 8 以降
  * 任意: Auth0 CLI のセットアップ用の **[jq](https://jqlang.org/)**、および安全なシークレットを生成するための **openssl**
  * Hono プロジェクトでは Hono >= 3.x を使用してください (ピア依存関係)
</Note>

<div id="get-started">
  ## はじめに
</div>

このクイックスタートでは、`@auth0/auth0-hono` を使用して Hono アプリケーションを保護するための最小限かつ推奨の方法を説明します。ここでは、リポジトリで推奨されているパターン、つまり環境変数ベースの設定、`app.use(auth0(...))` ミドルウェア、必要なルートだけを保護するための `requiresAuth()` に従います。

<Steps>
  <Step title="新しい Hono アプリケーションを作成する" stepNumber={1}>
    create-hono ユーティリティで新しい Hono アプリケーションを作成します。

    ```shellscript theme={null}
    npm create hono@latest auth0-hono-app && cd auth0-hono-app
    ```

    `nodejs` テンプレートを選択
  </Step>

  <Step title="依存関係をインストール" stepNumber={2}>
    Auth0 のミドルウェアをインストールします。

    ```shellscript theme={null}
    npm install @auth0/auth0-hono
    ```

    このクイックスタートでは、`.env` ファイルから環境変数を読み込むために `dotenv` パッケージを使用します。

    `dotenv` をローカル環境にインストールするには:

    ```shellscript theme={null}
    npm install -D dotenv
    ```

    また、依存関係を追加したくない場合は、Node.js の `--env-file` フラグを使用して、プロセスの起動時に env ファイルを読み込むこともできます。これにより、`dotenv` のインストールやインポートを省略できます。

    `package.json` の `start` スクリプトを次のように変更します。

    ```json theme={null}
      "scripts": {
        "start": "node --env-file=.env dist/index.js"
      }
    ```
  </Step>

  <Step title="Auth0 アプリケーションを作成する" stepNumber={3}>
    Auth0 テナントに Auth0 アプリケーション (Regular Web Application) を作成し、**ドメイン**、**クライアントID**、**クライアントシークレット** をプロジェクトの環境変数に設定します。
    CLI コマンドを実行して自動的に行うことも、Dashboard で手動で行うこともできます。

    <Tabs>
      <Tab title="CLI">
        Auth0 アプリを作成し、`.env` ファイルを生成するには、プロジェクトのルートディレクトリで次のシェルコマンドを実行します。

        <AuthCodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="Hono Quickstart" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t regular -c http://localhost:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json --metadata created_by="quickstart-docs-cli" > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && CLIENT_SECRET=$(jq -r '.client_secret' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && SECRET=$(openssl rand -hex 32) && echo "AUTH0_DOMAIN=${DOMAIN}" > .env && echo "AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && echo "AUTH0_CLIENT_SECRET=${CLIENT_SECRET}" >> .env && echo "APP_BASE_URL=http://localhost:3000" >> .env && echo "AUTH0_SESSION_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env && rm auth0-app-details.json && cat .env
          ```

          ```shellscript Windows theme={null}
          $AppName = "Hono Quickstart"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t regular -c http://localhost:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json --metadata created_by="quickstart-docs-cli" | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $ClientSecret = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_secret; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; $Secret = [System.Convert]::ToHexString([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32)).ToLower(); Set-Content -Path .env -Value "AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "AUTH0_CLIENT_ID=$ClientId"; Add-Content -Path .env -Value "AUTH0_CLIENT_SECRET=$ClientSecret"; Add-Content -Path .env -Value "AUTH0_SESSION_ENCRYPTION_KEY=$Secret"; Add-Content -Path .env -Value "APP_BASE_URL=http://localhost:3000"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env
          ```
        </AuthCodeGroup>

        生成された `.env` を使用するか、必要に応じて値を手動で更新してください。
      </Tab>

      <Tab title="Dashboard">
        手動で設定する手順:

        1. [Auth0 Dashboard](https://manage.auth0.com/dashboard/) に移動します
        2. Applications → Create Application → **Regular Web Application**
        3. アプリの設定で次の値を設定します:

        **Allowed Callback URLs**

        ```
        http://localhost:3000/auth/callback
        ```

        **Allowed Logout URLs**

        ```
        http://localhost:3000
        ```

        4. プロジェクトのルートに `.env` ファイルを作成し、次の値を設定します:

        ```env theme={null}
        AUTH0_DOMAIN=YOUR_AUTH0_DOMAIN
        AUTH0_CLIENT_ID=YOUR_AUTH0_CLIENT_ID
        AUTH0_CLIENT_SECRET=YOUR_AUTH0_CLIENT_SECRET
        APP_BASE_URL=http://localhost:3000
        AUTH0_SESSION_ENCRYPTION_KEY=your_32_char_min_secret
        # API を使用する場合は任意
        AUTH0_AUDIENCE=YOUR_API_IDENTIFIER
        ```

        注: `AUTH0_SESSION_ENCRYPTION_KEY` は 32 文字以上である必要があります。生成するには `openssl rand -hex 32` を使用してください。
      </Tab>
    </Tabs>
  </Step>

  <Step title="Auth0 ミドルウェアを使用して Hono Webサーバーをセットアップする" stepNumber={4}>
    `index.ts` ファイル内の初期テンプレートを、次の例に置き換えます。このコードは、環境変数を自動的に読み込むゼロコンフィグ設定を示しており、デフォルトで公開ルートを持つ `auth0()` ミドルウェアと、`requiresAuth()` を使用する保護されたルートを作成します。

    ```typescript ./src/index.ts wrap lines theme={null}
    // src/index.ts
    import { serve } from '@hono/node-server';
    import { Hono } from 'hono';
    import { auth0, requiresAuth, Auth0Error, type OIDCEnv } from '@auth0/auth0-hono';

    const app = new Hono<OIDCEnv>();

    // ゼロ設定: AUTH0_DOMAIN、AUTH0_CLIENT_ID、AUTH0_CLIENT_SECRET、
    // APP_BASE_URL、AUTH0_SESSION_ENCRYPTION_KEY を環境変数から読み込む
    app.use(
      auth0({
        authRequired: false, // デフォルトで公開、特定のルートを保護
      })
    );

    // 公開ルート
    app.get('/', (c) => c.text('Public — no login required'));

    // 保護されたルート
    app.use('/profile/*', requiresAuth());

    app.get('/profile', (c) => {
      const user = c.var.auth0.user;
      return c.json({ message: 'Protected profile', user });
    });

    // エラー処理
    app.onError((err, c) => {
      if (err instanceof Auth0Error) {
        return c.json({ error: err.code, error_description: err.description }, err.status);
      }
      return c.json({ error: 'Internal server error' }, 500);
    });

    const port = Number(process.env.PORT) || 3000;
    serve({ fetch: app.fetch, port }, (info) => {
      console.log(`Server is running on http://localhost:${info.port}`);
    });
    ```
  </Step>

  <Step title="アプリを実行する" stepNumber={5}>
    サーバーを起動し、`http://localhost:3000` を開きます。

    ```shellscript theme={null}
    npm run dev
    ```
  </Step>
</Steps>

<Check>
  **チェックポイント**

  Hono アプリが [http://localhost:3000](http://localhost:3000) で実行されているはずです。`/` ルートは公開されています。`/profile` にアクセスすると、ログイン画面にリダイレクトされ (未認証の場合) 、認証に成功するとプロフィールデータが返されるはずです。
</Check>

<div id="troubleshooting">
  ## トラブルシューティング
</div>

<Accordion title="よくある問題">
  <Accordion title="コールバックまたはリダイレクトの不一致">
    原因: Auth0 Dashboard で設定したコールバック URL が、`APP_BASE_URL` + コールバックルート (例: `http://localhost:3000/auth/callback`) と完全には一致していません。

    対処:

    1. `.env` の `APP_BASE_URL` の値を確認します。
    2. Auth0 Dashboard の Allowed Callback URLs に `http://localhost:3000/auth/callback` が含まれていることを確認します。
    3. 変更後に開発サーバーを再起動します。
  </Accordion>

  <Accordion title="セッションの復号 / JWEDecryptionFailed">
    原因: `AUTH0_SESSION_ENCRYPTION_KEY` が設定されていないか短すぎるか、古いシークレットで発行された Cookie が残っている状態でキーを変更した可能性があります。

    対処:

    * `AUTH0_SESSION_ENCRYPTION_KEY` が 32 文字以上であることを確認します。
    * キーを変更した後、localhost のブラウザー Cookie を削除します。
    * 開発サーバーを再起動します。
  </Accordion>

  <Accordion title="ルートが 404 を返す（例: /auth/login が 404 を返す）">
    原因: ミドルウェアがインストールされていないか、ルート登録の後に配置されています。

    対処:

    * `app.use(auth0(...))` が、認証に依存するルートより前に実行されることを確認します。
    * パッケージがインストールされていることを確認します: `npm ls @auth0/auth0-hono`。
  </Accordion>

  <Accordion title="本番環境で環境変数が見つからない">
    原因: デプロイ先のプラットフォームで環境変数が設定されていないか、異なる名前が使われています。

    対処:

    * ホスティングプロバイダーのダッシュボードで、環境変数をこのクイックスタートで使用している名前に対応付けます。
    * Cloudflare Workers では、セッションや Cookie の処理がプラットフォームと互換性があることを確認します。
  </Accordion>
</Accordion>

<div id="advanced-usage">
  ## 高度な使い方
</div>

* 選択的な保護: `app.use(auth0({ authRequired: false }))` を使用すると、デフォルトでルートを公開し、`app.use('/private/*', requiresAuth())` を使用すると、特定のパスを保護できます。
* サイレントログイン: `attemptSilentLogin()` ミドルウェアを使用してサイレント認証を試行し、UX を向上させます。
* カスタムログインフロー: `login({...})` を呼び出して、引き継ぐクエリパラメーター、`redirectAfterLogin`、またはサイレントログインのオプションをカスタマイズします。
* トークン管理: ミドルウェアはセッション経由でアクセストークンとIDトークンを公開します。スコープには最小権限の原則を適用し、リフレッシュトークンは安全にローテーションしてください。

<div id="best-practices-security">
  ## ベストプラクティスとセキュリティ
</div>

* シークレットはソース管理に含めず、環境変数を使用してください。
* 32 文字以上の `AUTH0_SESSION_ENCRYPTION_KEY` を使用してください。
* 本番環境では、cookie の `secure` を `true` に設定し、適切な `sameSite` ポリシーを設定してください。
* トークンのスコープは最小限に抑え、オーディエンスは API 用のアクセストークンをリクエストする場合にのみ使用してください。
* 認証固有のエラーを適切に処理できるよう、`app.onError` で `Auth0Error` をキャッチしてください。

***
