> ## 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.

# OIDC バックチャネルログアウト

> バックチャネルログアウトでは、ユーザーの SSO セッションが終了すると、すべての Relying Party にサーバー間のログアウトトークンが送信され、アプリケーションがそれぞれのセッションを終了できるようになります。

Auth0 は、Enterprise プランのサブスクリプションをご利用のすべてのテナントで、[OpenID Connect Back-Channel Logout 1.0 specification](https://openid.net/specs/openid-connect-backchannel-1_0.html#Backchannel) をサポートしています。

この仕様では、<Tooltip tip="ID トークン: リソースへのアクセスではなく、クライアント自体を対象とした資格情報。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=ID+tokens">ID トークン</Tooltip> に含まれるセッション ID (`sid`) と ログアウトトークン を利用して、バックチャネル通信によるセッション終了を調整します。異なるセッション ID は、テナント内のユーザーエージェントまたはデバイスごとの個別のセッションを表します。ログアウトトークン は、ログアウト対象のエンドユーザーとセッションを識別します。

<div id="back-channel-communications">
  ## バックチャネル通信
</div>

バックチャネルログアウト を使用するには、アプリケーションが バックチャネルログアウト URI を公開している必要があります。この URI はテナントサーバーからアクセス可能で、アプリケーションはここで ログアウトトークン を含むリクエストを受信します。アプリケーションがこのリクエストを受け取った場合、トークン内のクレームに一致するローカルのセッション状態をクリアする必要があります。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  バックチャネル logout を機能させるには、アプリケーションがバックチャネル通信を受信できる必要があります。
</Callout>

<div id="tokens-in-oidc-back-channel-logout-communications">
  ### OIDC バックチャネル Logout 通信で使用されるトークン
</div>

通信がバックチャネル経由で行われる場合、アプリケーションはどのセッションを終了すべきかを判断するために <Tooltip tip="セッションクッキー: 存在する場合、ユーザーが認証済みであると見なされるエンティティ。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=session+cookies">セッションクッキー</Tooltip> に頼ることはできません。代わりに、サービスは ID トークンと Logout トークンに含まれる共有セッション識別子 (`sid`) を使用します。

エンドユーザーが login 時に Auth0 で正常に認証されると、<Tooltip tip="認可サーバー: ユーザーのアクセス範囲の境界を定義するのに寄与する集中管理サーバー。たとえば、認可サーバーはユーザーが利用できるデータ、タスク、機能を制御できます。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=authorization+server">認可サーバー</Tooltip> はアクセストークンと ID トークンを発行します。Logout トークンは、logout アクションやセッションの失効などによってセッションが破棄されると生成されます。ID トークンと Logout トークンの両方には、バックチャネル Logout ワークフローを実行するためにアプリケーションが必要とするクレームが含まれています。クレームの詳細については、[JSON Web Token Claims](/docs/ja-jp/secure/tokens/json-web-tokens/json-web-token-claims) をお読みください。

<Frame>
  <img src="https://mintcdn.com/translations/MV7tE-x71x8RWRES/docs/images/cdy7uua7fh8z/5jQ5HogFNeD9tqUGEJuJHE/663f1f52b285f7019fd1157f5a26caf0/2023-09-29_09-32-00.png?fit=max&auto=format&n=MV7tE-x71x8RWRES&q=85&s=2b7fbbaf0b09b46cf3f64b42509b7bc7" alt="バックチャネル logout のワークフロー" width="849" height="324" data-path="docs/images/cdy7uua7fh8z/5jQ5HogFNeD9tqUGEJuJHE/663f1f52b285f7019fd1157f5a26caf0/2023-09-29_09-32-00.png" />
</Frame>

1. Login - ユーザー認証時に、Auth0 テナントは `sid` を ID トークンに追加します。
2. Login - アプリケーションは受け取ったセッション識別子を独自のセッションストアに保存し、アプリケーション固有のセッションに関連付けます。
3. Logout - IdP は事前に登録された logout コールバック URL を呼び出し、このエンドポイントに Logout トークンを POST します。トークンには、他のパラメーターとともに `user_id` (`sub`) と `sid` が含まれます。
4. Logout - アプリケーションのバックエンドは、OIDC 仕様に従って Logout トークンを検証し、`sid` を抽出する必要があります。その後、バックエンドはこのトークンを使用して、その識別子に関連付けられたセッションを特定し、必要に応じて終了できます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  logout が成功した場合に期待されるレスポンスは `HTTP 200` です。`HTTP 400` (不正または誤って解釈された request) を受け取った場合は、トラブルシューティングのヒントを活用できます。詳細については、[バックチャネル Logout を設定する](/docs/ja-jp/authenticate/login/logout/back-channel-logout/configure-back-channel-logout) をお読みください。
</Callout>

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

このサンプルユースケースでは、複数のアプリケーションで バックチャネルログアウト がどのように機能するかを示します。

<Frame>
  <img src="https://mintcdn.com/translations/MV7tE-x71x8RWRES/docs/images/cdy7uua7fh8z/54mbNobsvLec0A2tz0DXUG/99ce79c9e93ffe526472d6250373778c/2023-06-20_09-39-12.png?fit=max&auto=format&n=MV7tE-x71x8RWRES&q=85&s=0af402480a71445e216e9cc5427d3aca" alt="複数アプリケーションでのバックチャネルログアウトのユースケース" width="2476" height="2562" data-path="docs/images/cdy7uua7fh8z/54mbNobsvLec0A2tz0DXUG/99ce79c9e93ffe526472d6250373778c/2023-06-20_09-39-12.png" />
</Frame>

1. アプリケーションの設定時に、アプリケーション A は バックチャネルログアウト URI を Auth0 に登録します。
2. アプリケーションの設定時に、アプリケーション B は バックチャネルログアウト URI を Auth0 に登録します。

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     OIDC バックチャネルログアウト URL は、次の要件を満たす必要があります。

     * IdP からアクセスできること
     * TLS で暗号化されたエンドポイントを使用すること
     * [ログアウトトークン を検証する](https://openid.net/specs/openid-connect-backchannel-1_0.html#Validation)
   </Callout>
3. エンドユーザーの login 時に、ユーザーはアプリケーション A にアクセスするため Auth0 で認証されます。
4. Auth0 は `sid` を含む ID トークンをアプリケーション A に送信します。詳しくは、[ID Token Structure](/docs/ja-jp/secure/tokens/id-tokens/id-token-structure) を参照してください。
5. ユーザーはアプリケーション B にアクセスするため Auth0 で認証されます。
6. Auth0 は同じ `sid` を含む ID トークンをアプリケーション B に送信します。アプリケーションでは、このセッション情報を保存する必要があります。
7. logout 時に、アプリケーション A または他のエンティティがフロントチャネルで logout を開始します。
8. Auth0 はセッションクッキーを通じて Auth0 セッション層を終了します。
9. Auth0 はアプリケーション A の バックチャネルログアウト URI を呼び出し、ログアウトトークン を POST します。
10. アプリケーション A は ログアウトトークン を検証し、セッションを終了します。
11. Auth0 はアプリケーション B の バックチャネルログアウト URI を呼び出し、ログアウトトークン を POST します。
12. アプリケーション B は ログアウトトークン を検証し、セッションを終了します。

バックチャネルログアウトの request は非同期キューに入れられ、できるだけ速やかに処理されます。高負荷時には、logout request が実行されるまでにわずかな遅延が生じる場合があるため、この結果整合性に対応できるようアプリケーションを設計してください。

<div id="sample-token">
  #### サンプルトークン
</div>

Auth0 で ログアウトトークン として使用するには、アプリケーションが <Tooltip tip="JSON Web Token (JWT): 2者間でクレームを安全に表現するために使用される標準的な ID トークン形式（多くの場合、アクセストークン形式でもあります）。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=JWTs">JWTs</Tooltip> を解析し、検証できる必要があります。詳しくは、[JSON Web Tokens を検証する](/docs/ja-jp/secure/tokens/json-web-tokens/validate-json-web-tokens)をご覧ください。

アプリケーションでトークンを検証してデコードすると、その内容は次の例のようになります。

```json JSON lines theme={null}
{
  "iss": "https://artex-dev.eu.auth0.com/",
  "sub": "auth0|602e93db83fa6f00749a23e6",
  "aud": "TuhNLv7ulXD3RfyLlSMbOvszzwJJFPpO",
  "iat": 1698160928,
  "exp": 1698161048,
  "jti": "44a91215-dfb4-4dfe-a1eb-fcafa911deba",
  "events": {
    "http://schemas.openid.net/event/backchannel-logout": {}
  },
  "trace_id": "81b336a94a4a5707",
  "sid": "375UIp_ID5mCTClIeBEHpXfGwq51tF_L"
}
```

<div id="auth0-sdks">
  ### Auth0 SDK
</div>

完全なサンプルと本番環境向けのコードは、[express-openid-connect SDK](https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md#11-back-channel-logout) の **バックチャネル ログアウトの例** セクションにすでに含まれています。

<div id="implementation-examples">
  ## 実装例
</div>

<div id="session-storage">
  ### セッションストレージ
</div>

このセッションストレージの例は Node (Express) で構築されており、[Express OpenID Connect Web App Sample](https://github.com/auth0-samples/auth0-express-webapp-sample/tree/master/01-Login) をベースにしています。

アプリケーションの sessions タブで、Logout Token を受け取るよう設定したルートを公開します。トークンを検証し、ユーザーセッションを終了します。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  この例では、デモ目的でインメモリのセッションストアを使用しています。
</Callout>

```javascript routes/index.js lines expandable theme={null}
const express = require('express');
const router = express.Router();
const { requiresAuth } = require('express-openid-connect');

// ログアウトトークンを検証するミドルウェア
const requiresValidLogoutToken = require('../middlewares/validateLogoutToken');

// ユーザーセッションを削除するヘルパー関数
const deleteUserSessions = require('../utils/sessions');

// バックチャネルログアウトトークンを受信する新しいルート
// Auth0 Management Dashboard の Application -> Sessions タブで
// 設定する必要があります
router.post(
  '/backchannel-logout',
  requiresValidLogoutToken,
  function (req, res, next) {
    // この時点でログアウトトークンは有効です（requiresValidLogoutToken ミドルウェアによる検証済み）
    // リクエストオブジェクトからアクセスできます: req.logoutToken

    // ユーザーセッションを削除してログアウトさせる
    deleteUserSessions(
      req.app.locals.sessionStore,
      req.logoutToken.sub,
      req.logoutToken.sid
    );

    res.sendStatus(200);
  }
);

router.get('/', function (req, res, next) {
  res.render('index', {
    title: 'Auth0 Webapp sample Nodejs',
    isAuthenticated: req.oidc.isAuthenticated(),
    headline: process.env.APP_NAME,
    backgroundColor: process.env.BACKGROUND_COLOR,
    baseURL: process.env.BASE_URL,
  });
});

router.get('/profile', requiresAuth(), function (req, res, next) {
  res.render('profile', {
    userProfile: JSON.stringify(req.oidc.user, null, 2),
    title: 'Profile page',
    headline: process.env.APP_NAME,
    backgroundColor: process.env.BACKGROUND_COLOR,
    baseURL: process.env.BASE_URL,
  });
});

module.exports = router;
```

```javascript middlewares/validateLogoutToken.js lines expandable theme={null}
// このミドルウェアは、以下で定義されているログアウトトークンを検証します:
// https://openid.net/specs/openid-connect-backchannel-1_0.html#Validation

const jose = require('jose');

async function requiresValidLogoutToken(req, res, next) {

  // トークン検証用のリモートキーセットを取得する
  const JWKS = jose.createRemoteJWKSet(
    new URL(process.env.ISSUER_BASE_URL + '/.well-known/jwks.json')
  );

  const logoutToken = req.body.logout_token;

  if (!logoutToken) {
    res.status(400).send('Need logout token');
  }

  try {
    const { payload, protectedHeader } = await jose.jwtVerify(
      logoutToken,
      JWKS,
      {
        issuer: process.env.ISSUER_BASE_URL + '/',
        audience: process.env.CLIENT_ID,
        typ: 'JWT',
        maxTokenAge: '2 minutes',
      }
    );

    // ログアウトトークンに sub クレーム、sid クレーム、またはその両方が含まれていることを確認する
    if (!payload.sub && !payload.sid) {
      res
        .status(400)
        .send(
          'Error: Logout token must contain either sub claim or sid claim, or both'
        );
    }

    // ログアウトトークンに events クレームが含まれていることを確認する
    // その値は、メンバー名 http://schemas.openid.net/event/backchannel-logout を含む JSON オブジェクトであること
    if (!payload.events['http://schemas.openid.net/event/backchannel-logout']) {
      res
        .status(400)
        .send(
          'Error: Logout token must contain events claim with correct schema'
        );
    }

    // ログアウトトークンに nonce クレームが含まれていないことを確認する
    if (payload.nonce) {
      res
        .status(400)
        .send('Error: Logout token must not contain a nonce claim');
    }

    // 有効なログアウトトークンをリクエストオブジェクトに付加する
    req.logoutToken = payload;

    // トークンは有効、次のミドルウェアを呼び出す
    next();
  } catch (error) {
    res.status(400).send(`Error:  ${error.message}`);
  }
}

module.exports = requiresValidLogoutToken;
```

<div id="logout-token-store">
  ### ログアウトトークンストア
</div>

トークン保存の一般的な方法として、セッションストアモデルの代わりにログアウトストアを定義する方法があります。アプリケーションは、永続化層に ログアウトトークン のコレクションを保持します。

アプリケーションが認証状態を確認する必要があるたびに、ログアウトトークンストアを照会して、セッションがまだ有効かどうかを確認します。ログアウトストアは、必要な情報だけを残すために、古い情報を定期的に削除します。

<Frame>
  <img src="https://mintcdn.com/translations/Dcx0M11uuptU53TX/docs/images/cdy7uua7fh8z/2zTtcie1d0fjiSuxZ4huyV/dbcf45fb68a045bd1b1918315f8025f7/image__21_.png?fit=max&auto=format&n=Dcx0M11uuptU53TX&q=85&s=a5dcbbfe2b72204119f6f3447334799c" alt="ログアウトトークンストア" width="2978" height="1144" data-path="docs/images/cdy7uua7fh8z/2zTtcie1d0fjiSuxZ4huyV/dbcf45fb68a045bd1b1918315f8025f7/image__21_.png" />
</Frame>

<div id="security-considerations">
  ## セキュリティに関する考慮事項
</div>

Back-Channel Logout Tokens はインターネット経由で配信されるため、それらを受信するコールバックエンドポイントは、信頼性と安全性を確保するためにベストプラクティスに従う必要があります。以下の推奨事項は網羅的なものではないため、実際のデプロイや運用状況に応じて適宜判断する必要があります。以下の一覧では、Back-Channel Logout Tokens を処理するアプリを「アプリ」と呼びます。

* アプリは、後で Back-Channel Logout token を受信した際に参照できるよう、ユーザーの login 時に受信したセッション ID (`sid` claim) を保存できなければなりません。
* アプリは、受信した token を [JWT 検証のベストプラクティス](/docs/ja-jp/secure/tokens/json-web-tokens/validate-json-web-tokens) に従って検証しなければなりません。
* アプリは、信頼できるテナントによって発行された token のみを受け入れなければなりません。悪意のある第三者が他の Auth0 テナントによって発行された token を送信しようとする可能性があるため、そのような試みは拒否しなければなりません。
* アプリは、アプリが認識できる `sid` 値 (セッション ID) を含む token のみを受け入れなければなりません。無効なセッション ID (期限切れまたは未認識) を含む token は拒否しなければなりません。
* アプリは、コールバックエンドポイントを TLS 経由でのみ公開しなければなりません。暗号化されていない通信チャネルは許可されません。
* アプリは、公開されている [送信元 IP アドレス](/docs/ja-jp/secure/security-guidance/data-security/allowlist) の一覧からの request のみを受け入れることが推奨されます。
* アプリは、監視、ログ、およびレート制限に関する一般的なベストプラクティスに従うことが推奨されます。ただし、これらの詳細はこのドキュメントの範囲外です。
* アプリは、古くなったセッションや期限切れのセッションを定期的に削除することが推奨されます。
* endpoint アドレスに変更がある場合は、ログアウトトークンs が常に正しい Back-Channel Logout Callback URL に配信されるよう、テナントの設定と同期しなければなりません。
