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

{% hint style="warning" %}
このガイドでは、ドキュメント用の保護されたサインイン画面の設定方法を説明します。このガイドに進む前に、まず次の手順を完了していることを確認してください [認証済みアクセスを有効にする](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/authenticated-access/enabling-authenticated-access).
{% endhint %}

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

{% hint style="info" %}
サポートされている認証プロバイダーのいずれかを使用しているか、 [OpenID Connect](https://auth0.com/docs/authenticate/protocols/openid-connect-protocol) （OIDC）準拠のバックエンドをお持ちの場合は、よりスムーズな設定のために統合ガイドをご覧ください：\
\
[Auth0](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/authenticated-access/setting-up-auth0) | [Azure AD](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/authenticated-access/setting-up-azure-ad) | [Okta](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/authenticated-access/setting-up-okta) | [AWS Cognito](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/authenticated-access/setting-up-aws-cognito) | [OIDC](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/authenticated-access/setting-up-oidc)
{% 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-login-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 に渡し** 〜するとき **リダイレクトする** ユーザーをサイトへ戻します。トークンは次のものを使用して署名する必要があります： **秘密鍵** サイトの audience 設定で提供される [認証済みアクセスを有効にする](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/enabling-authenticated-access#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 %}

#### GitBook セッションから訪問者をサインアウトする

訪問者を GitBook セッションからサインアウトするには、サイト URL に `~gitbook/auth/logout` を末尾に付けます：

`https://mycompany.gitbook.io/myspace/~gitbook/auth/logout`

このエンドポイントは、訪問者を GitBook からサインアウトするだけです。独自の ID プロバイダーからもサインアウトさせたい場合は、独自のログアウトフローで別途処理してください。

### 3. ログイン URL を構成する

ログイン URL は、認証されていない訪問者が保護されたサイトにアクセスしようとしたときに使用されます。GitBook はその後、この URL にリダイレクトします。

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

たとえば、ログイン画面が `https://example.com/login`にある場合、その値をログイン URL として指定してください。

このログイン URL は、サイトの audience 設定の「Authenticated access」タブで構成できます。

<figure><img src="https://4217681718-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNkEGS7hzeqa35sMXQZ4X%2Fuploads%2FB48PEdMz1tCDf0Q0lo4d%2FScreenshot%202025-03-25%20at%2015.00.08.png?alt=media&#x26;token=e22fe867-e1f6-44f7-8b4f-a868ac620464" alt="A GitBook screenshot showing where to configure a login 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 を次のように設定できます：

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

```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. アダプティブコンテンツ用にバックエンドを構成する（オプション）

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

これらのクレームは JWT に含まれていると、GitBook によって [コンテンツを適応させる](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/adaptive-content/adapting-your-content) ために動的に使われます。

全体をまとめると、次のコード例ではこれらのクレームを 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 に送信する適切なクレームの設定と構成が完了したら、「[コンテンツを適応させる](https://gitbook-v2-5hpihs24d-gitbook.vercel.app/url/gitbook.com/docs/documentation/ja-gitbook-documentation/saitohenoakusesu/adaptive-content/adapting-your-content)」へ進み、サイトの設定を続けてください。
