# カスタムバックエンドの設定

{% hint style="warning" %}
このガイドでは、ドキュメント用の保護されたサインイン画面の設定方法を順を追って説明します。このガイドに進む前に、まず次の手順を済ませておいてください。 [認証済みアクセスを有効にする](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/enabling-authenticated-access.md).
{% endhint %}

このガイドでは、独自の **カスタム** 認証バックエンドを使用して、GitBook のドキュメントサイト用の保護されたサインイン画面を設定する方法を説明します。

{% hint style="info" %}
当社がサポートする認証プロバイダーのいずれかを使用している場合、または [OpenID Connect](https://auth0.com/docs/authenticate/protocols/openid-connect-protocol) （OIDC）準拠のバックエンドをお持ちの場合は、よりスムーズに設定できる統合ガイドをご覧ください。\
\
[Auth0](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/setting-up-auth0.md) | [Azure AD](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/setting-up-azure-ad.md) | [Okta](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/setting-up-okta.md) | [AWS Cognito](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/setting-up-aws-cognito.md) | [OIDC](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/setting-up-oidc.md)
{% endhint %}

### 概要

GitBook サイトにカスタム認証システムを設定するには、次の主要な手順に従います。

{% stepper %}
{% step %}
[**ユーザーを認証するためのカスタムバックエンドを作成する**](#id-1.-create-a-custom-backend-to-authenticate-your-users)

ユーザーにログインを促し、認証するバックエンドを実装します。
{% endstep %}

{% step %}
[**JWT トークンに署名して GitBook に渡す**](#id-2.-sign-and-pass-a-jwt-token-to-gitbook)

JWT トークンを作成し、サイトの秘密鍵で署名します。
{% endstep %}

{% step %}
[**フォールバック URL を設定する**](#id-3.-configure-a-fallback-url)

未認証の訪問者がサイトにアクセスしたときに使用される URL を設定します。
{% endstep %}

{% step %}
[**マルチテナント認証済みアクセスを設定する（任意）**](#id-4.-set-up-multi-tenant-authenticated-access)

複数の GitBook サイトにまたがる認証を処理するようにバックエンドを設定します。
{% endstep %}

{% step %}
[**アダプティブコンテンツ用にバックエンドを設定する（任意）**](#id-5.-configure-your-backend-for-adaptive-content)

GitBook のアダプティブコンテンツで動作するようにバックエンドを設定します。
{% endstep %}
{% endstepper %}

### 1. ユーザーを認証するためのカスタムバックエンドを作成する

ユーザーがドキュメントを閲覧できるようになる前に認証を開始するには、ユーザーのログインと認証を処理できるサーバーを設定する必要があります。

バックエンドは次を満たす必要があります。

* ユーザーに、好みの認証方法でログインするよう促す。
* ユーザーの認証情報を検証し、認証する。
* 次を生成して署名する **JSON Web Token（JWT）** 認証成功時に。
* JWT を URL に含めて、ユーザーを GitBook にリダイレクトする。

### 2. JWT トークンに署名して GitBook に渡す

バックエンドがユーザーを認証したら、 **JWT を生成し** 、 **GitBook に渡す** 際に **リダイレクト** してサイトへ送る必要があります。トークンは、 **秘密鍵** を使って署名してください。これは、 [認証済みアクセスを有効にする](/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/enabling-authenticated-access.md#enable-authenticated-access).

以下の例は、カスタムバックエンド内のログインリクエストハンドラーがどのように見えるかを示しています。

{% code title="index.ts" %}

```typescript
import { Request, Response } from 'express';
import * as jose from 'jose';

import { getUserInfo } from '../services/user-info-service';
import { getFeatureFlags } from '../services/feature-flags-service';

const GITBOOK_VISITOR_SIGNING_KEY = process.env.GITBOOK_VISITOR_SIGNING_KEY!;
const GITBOOK_DOCS_URL = 'https://mycompany.gitbook.io/myspace';

export async function handleAppLoginRequest(req: Request, res: Response) {
    // ログインリクエストを処理するためのビジネスロジック
    // たとえば、認証情報を確認してユーザーを認証する
    //
    // 例：
    // const loggedInUser = await authenticateUser(req.body.username, req.body.password);
    
    // 署名済み JWT を生成する
    const gitbookVisitorJWT = await new jose.SignJWT({})
        .setProtectedHeader({ alg: 'HS256' })
        .setIssuedAt()
        .setExpirationTime('2h') // 任意の 2 時間の有効期限
        .sign(new TextEncoder().encode(GITBOOK_VISITOR_SIGNING_KEY));
    
    // JWT トークンを URL に含めてユーザーを GitBook にリダイレクトする
    const redirectURL = `${GITBOOK_DOCS_URL}/?jwt_token=${gitbookVisitorJWT}`;
    res.redirect(redirectURL);
}
```

{% endcode %}

### 3. フォールバック URL を設定する

フォールバック URL は、未認証の訪問者が保護されたサイトにアクセスしようとしたときに使用されます。その後、GitBook はその訪問者をこの URL にリダイレクトします。

この URL は、カスタムバックエンド内のハンドラーを指している必要があります。そこでログインを促し、認証し、JWT を URL に含めてサイトへ戻すリダイレクトを行います。

たとえば、ログイン画面の場所が `https://example.com/login`であれば、この値をフォールバック URL として含めてください。

このフォールバック URL は、サイトのオーディエンス設定の「Authenticated access」タブで設定できます。

<figure><img src="/files/fc473597f811f51c88a5c78cd65aebcac725b8e1" alt="A GitBook screenshot showing where to configure a fallback URL"><figcaption><p>フォールバック URL を設定する</p></figcaption></figure>

#### GitBook のログインエンドポイントを使う

公開サイトにサインインリンクを置きたい場合は、次へリンクしてください。 `<publishedSiteURL>/~gitbook/auth/login`.

このエンドポイントは、訪問者をそのサイトに設定された認証バックエンドへリダイレクトします。また、 `location` というクエリパラメータも追加され、訪問者が開始したページと一致します。

これは、ヘッダーリンクなど、サインイン後に訪問者を同じページへ戻したい場合に便利です。

フォールバック URL にリダイレクトするとき、GitBook は `location` クエリパラメータをフォールバック URL に含めます。これをハンドラーで利用して、ユーザーを元の場所へリダイレクトできます。

```javascript
const gitbookVisitorJWT = await new jose.SignJWT({})
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime('2h') // 任意の 2 時間の有効期限
    .sign(new TextEncoder().encode(GITBOOK_VISITOR_SIGNING_KEY));
    
// JWT を jwt_token クエリパラメータとして含めて、元の GitBook ドキュメント URL にリダイレクトする
// location が指定されている場合、ユーザーは元の移動先に戻される
const redirectURL = `${GITBOOK_DOCS_URL}/${req.query.location || ''}?jwt_token=${gitbookVisitorJWT}`;
res.redirect(redirectURL);
```

{% hint style="warning" %}
GitBook は `location` search param に依存しているため、フォールバック URL では使用できません。たとえば、 `https://auth.gitbook.com/?location=something` は有効なフォールバック URL ではありません。
{% endhint %}

#### GitBook のログアウトエンドポイントを使う

公開サイトにサインアウトリンクを置きたい場合は、次へリンクしてください。 `<publishedSiteURL>/~gitbook/auth/logout`.

このエンドポイントは、訪問者を GitBook セッションからサインアウトさせます。

### 4. マルチテナント認証済みアクセスを設定する（任意）

GitBook を、異なる顧客にコンテンツを提供するプラットフォームとして使っている場合、マルチテナント認証済みアクセスを設定する必要があるでしょう。認証バックエンドは、複数の異なるサイトにまたがる認証処理を担当する必要があります。これは、カスタム認証バックエンドのコードに少し手を加えるだけで GitBook で実現できます。

#### すべてのテナントを認証サーバーに追加する

認証バックエンドは、JWT 署名キーと、処理対象となるすべての GitBook サイトの URL を知っている必要があります。組織内に Customer A と Customer B の 2 つのサイトがある場合、認証コードで次のようなマッピングを保存することができます。

```typescript
const CUSTOMER_A = {
  jwtSigningKey: 'aaa-aaa-aaa-aaa',
  url: 'https://mycompany.gitbook.io/customer-a'
};

const CUSTOMER_B = {
  jwtSigningKey: 'bbb-bbb-bbb-bbb',
  url: 'https://mycompany.gitbook.io/customer-b'
};
```

#### 認証サーバーに追加のコンテキストを与える

GitBook がユーザーのリクエストを認証できない場合、そのユーザーをフォールバック URL にリダイレクトします。この URL は認証バックエンドを指しており、そこでユーザーの認証と、要求されたコンテンツへの再リダイレクトを行います。

複数のテナントをサポートするには、ユーザーがどの GitBook サイトへアクセスすべきかを認証バックエンドが知る必要があります。この情報はフォールバック URL で渡すことができます。

たとえば、各サイトのフォールバック URL は次のように設定できます。

<table><thead><tr><th width="150.75390625">GitBook サイト</th><th>フォールバック URL</th></tr></thead><tbody><tr><td>Customer A のサイト</td><td><code>https://auth-backend.acme.org/login?site=customer-a</code></td></tr><tr><td>Customer B のサイト</td><td><code>https://auth-backend.acme.org/login?site=customer-b</code></td></tr></tbody></table>

その後、認証バックエンドはこの情報を確認し、それに応じて適切なサイトへのリダイレクトを処理できます。

```javascript
const customerInfo = req.query.site === 'customer-a' ? CUSTOMER_A : CUSTOMER_B;
  
const gitbookVisitorJWT = await new jose.SignJWT({})
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime('2h') // 任意の 2 時間の有効期限
    .sign(new TextEncoder().encode(customerInfo.jwtSigningKey));
    
// JWT を jwt_token クエリパラメータとして含めて、元の GitBook ドキュメント URL にリダイレクトする
// location が指定されている場合、ユーザーは元の移動先に戻される
const redirectURL = `${customerInfo.url}/${req.query.location || ''}?jwt_token=${gitbookVisitorJWT}`;
res.redirect(redirectURL);
```

### 5. アダプティブコンテンツ用にバックエンドを設定する（任意）

認証済みアクセス設定で Adaptive Content 機能を活用するには、カスタムバックエンドが生成する JWT のペイロードに追加のユーザー属性（クレーム）を含め、ユーザーをサイトへリダイレクトする際に URL に含めることができます。

これらのクレームは JWT に含められると、GitBook によって [コンテンツを動的に適応](/docs/documentation/ja-gitbook-documentation/saitoakusesu/adaptive-content/adapting-your-content.md) させるために使用されます。

まとめると、次のコード例は JWT にこれらのクレームを含める方法を示しており、GitBook はそれを使って訪問者向けにコンテンツを適応できます。

{% code title="index.ts" %}

```typescript
import { Request, Response } from 'express';
import * as jose from 'jose';

import { getUserInfo } from '../services/user-info-service';
import { getFeatureFlags } from '../services/feature-flags-service';

const GITBOOK_VISITOR_SIGNING_KEY = process.env.GITBOOK_VISITOR_SIGNING_KEY!;
const GITBOOK_DOCS_URL = 'https://mycompany.gitbook.io/myspace';

export async function handleAppLoginRequest(req: Request, res: Response) {
    // ログインリクエストを処理するためのビジネスロジック
    // たとえば、認証情報を確認してユーザーを認証する
    //
    // 例：
    // const loggedInUser = await authenticateUser(req.body.username, req.body.password);
    
    // この例では、ログイン済みユーザーのオブジェクトがあるものとします
    const loggedInUser = { id: '12345' }; // 実際の認証ロジックに置き換えてください

    // GitBook に渡すユーザー情報を取得する
    const userInfo = await getUserInfo(loggedInUser.id);
    
    // 署名済み JWT を生成し、ユーザー属性をクレームとして含める
    const gitbookVisitorClaims = {
        firstName: userInfo.firstName,
        lastName: userInfo.lastName,
        isBetaUser: userInfo.isBetaUser,
        products: userInfo.products.map((product) => product.name),
        featureFlags: await getFeatureFlags({ userId: loggedInUser.id })
    };
    
    const gitbookVisitorJWT = await new jose.SignJWT(gitbookVisitorClaims)
        .setProtectedHeader({ alg: 'HS256' })
        .setIssuedAt()
        .setExpirationTime('2h') // 任意の 2 時間の有効期限
        .sign(new TextEncoder().encode(GITBOOK_VISITOR_SIGNING_KEY));
    
    // JWT トークンを URL に含めてユーザーを GitBook にリダイレクトする
    const redirectURL = `${GITBOOK_DOCS_URL}/?jwt_token=${gitbookVisitorJWT}`;
    res.redirect(redirectURL);
}
```

{% endcode %}

GitBook に送信する適切なクレームの設定と構成が完了したら、「[コンテンツの適応](/docs/documentation/ja-gitbook-documentation/saitoakusesu/adaptive-content/adapting-your-content.md)」へ進んで、サイトの設定を続けてください。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.com/docs/documentation/ja-gitbook-documentation/saitoakusesu/authenticated-access/setting-up-a-custom-backend.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
