# 認証ウェブフック

## 概要

Sora は認証機能を持っていますが、クライアントからの接続可否を判断する機能は持っていません。 
接続可否は外部のアプリケーションサーバーにウェブフックを送信し、その戻り値で判断します。

Sora はシグナリング経由で送られてきた情報や、
そのチャネルに接続している情報を HTTP/1.1 POST で `sora.conf` の [auth_webhook_url](SORA_CONF.html#36a99a) に指定された URL へ送信します。
このとき送信する情報は JSON 形式です。

## 注意

シグナリング `"type": "connect"` 経由で送られてきた情報がそのまま認証ウェブフックのリクエストとして送信されるわけではありません。

### ログの出力

`sora.conf` の [auth_webhook_url](SORA_CONF.html#36a99a) を有効にしない場合でも `log/auth_webhook.jsonl` は生成されます。

## HTTP ヘッダー

> **警告**
>
> この機能は [実験的機能](EXPERIMENTAL.html) のため、正式版では仕様が変更される可能性があります

> **注釈**
>
> JSON のパース時の判断などに利用してください。

### sora-connection-id

認証ウェブフックの HTTP ヘッダー に `sora-connection-id` というヘッダー名でコネクション ID が入ってきます。

コネクション ID が `WCJC78EWK935N7P7Z8FYAKFW9M` の場合は `sora-connection-id: WCJC78EWK935N7P7Z8FYAKFW9M` のように値が入ってきます。

## 設定

### auth_webhook_url

**デフォルト**: 未設定

認証可否の判断に使用する HTTP リクエストの送信先を `sora.conf` の [auth_webhook_url](SORA_CONF.html#36a99a) に設定します。
認証ウェブフック機能を使用する場合は指定してください。

HTTP のレスポンスは認証の可否に関わらず、 200 OK 等 200 番台のステータスコードを返す必要があります。

```ini
auth_webhook_url = http://127.0.0.1:8080/sora/auth/webhook
```

### auth_webhook_log

> **危険**
>
> 何か特別な理由がない限り `false` へ変更しないでください。

**デフォルト**: true

認証ウェブフックがログを出力するかどうかを `sora.conf` の [auth_webhook_log](SORA_CONF.html#116686) で設定します。

- 認証ウェブフックが **正常に処理された場合** は `log/auth_webhook.jsonl` にログが出力されます
- 認証ウェブフックの **処理が失敗した場合** は `log/auth_webhook_error.jsonl` にログが出力されます- 戻りのステータスコードが 200 番台以外の場合
  - 戻りの JSON に `"allowed"` 項目が含まれていない場合
  - 戻りの JSON が `"allowed": false` で `"reason"` が含まれていない場合
  - 送信先が応答せずタイムアウトになった場合

## 認証処理時に送信する JSON

Sora は、 `sora.conf` の [auth_webhook_url](SORA_CONF.html#36a99a) に設定した URL に対して **POST リクエスト** で次のような JSON を送ります。

型については [認証ウェブフック](WEBHOOK_TYPE.html#cd90e9) を確認してください。

```javascript
{
  "audio": true,
  "audio_codec_type": "OPUS",
  "channel_connections": 0,
  "channel_id": "sora",
  "channel_recvonly_connections": 0,
  "channel_sendonly_connections": 0,
  "channel_sendrecv_connections": 0,
  "connection_id": "VSMDDJG3ZH1RHB93W260APVEQW",
  "data_channel_signaling": true,
  "data_channels": [
    {
      "compress": false,
      "direction": "sendrecv",
      "label": "#abc",
      "ordered": true
    }
  ],
  "e2ee": false,
  "ignore_disconnect_websocket": false,
  "label": "WebRTC SFU Sora",
  "node_name": "node1@192.0.2.10",
  "role": "sendrecv",
  "simulcast": false,
  "sora_client": {
    "environment": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.109 Safari/537.36",
    "raw": "Sora JavaScript SDK 2023.2.0",
    "type": "Sora JavaScript SDK",
    "version": "2023.2.0"
  },
  "spotlight": false,
  "timestamp": "2022-06-08T07:51:32.593704Z",
  "version": "2024.1.0",
  "video": true,
  "video_bit_rate": 1000,
  "video_codec_type": "VP9",
  "video_vp9_params": { "profile_id": 0 }
}
```

- version- Sora のバージョンが `文字列` で入ってきます
- label- `sora.conf` の [label](SORA_CONF.html#815983) で指定した値が入ってきます
- node_name- Sora のノード名が入ってきます
- timestamp- ウェブフックリクエスト送信時のタイムスタンプが RFC3339 フォーマットで入ってきます
  - マイクロ秒まで含まれています
- id- Base32-UUIDv4 です
  - ウェブフックごとに割り当てられるユニークな値です
- e2ee- 将来的に Message Layer Security (MLS) を利用した End to End Encryption (E2EE) に対応した際の予約項目です
  - 現時点では常に `false` が含まれます
- simulcast- サイマルキャストでの接続要求を出しているかどうかの値が入ってきます
  - `true` の場合はサイマルキャストを希望している接続です
  - クライアントが送ってこない場合は `false` が設定されます
- simulcast_rid- `simulcast` が `true` かつ `spotlight` が `false` の場合のみこの値が入ってきます
  - サイマルキャストでの受け取る rid を指定します
- simulcast_multicodec- `simulcast` が `true` の場合のみこの値が入ってきます
  - サイマルキャストマルチコーデックを利用するかどうかの値が入ってきます
- spotlight- スポットライトでの接続要求を出しているかどうかの値が入ってきます
  - クライアントが送ってこない場合は `false` が設定されます
- spotlight_focus_rid- `spotlight` が `true` の場合のみこの値が入ってきます
  - スポットライトでフォーカスされた参加者の映像を受信する rid を指定します
- spotlight_unfocus_rid- `spotlight` が `true` の場合のみこの値が入ってきます
  - スポットライトでフォーカスされていない参加者の映像を受信する rid を指定します
- spotlight_number- **この項目はオプションです**
  - クライアントが送ってこない場合は、この値は含まれません
  - `spotlight_number` をシグナリングの connect 時に送ってきた場合に値が入ります
- whip- WHIP を利用したシグナリングを利用するかどうかの値が入ってきます
- whep- WHEP を利用したシグナリングを利用するかどうかの値が入ってきます
- role- 以下が入ってきます
  - `sendrecv` (送受信)
  - `sendonly` (送信)
  - `recvonly` (受信)
- metadata- **この項目はオプションです**
  - ユーザーが定義を自由にできる値です
  - JSON で使用できる形式ならどんな値でも指定できます
  - `"type": "connect"` で `metadata` が送られてこない場合、アプリケーション側にも送られません
- authn_metadata- この項目は metadata と同じです
  - metadata の別名です
  - `"type": "connect"` で `metadata` が送られてこない場合、アプリケーション側にも送られません
- channel_id- 認証対象のクライアントが接続要求を出しているチャネル ID です
- client_id- **この項目はオプションです**
  - 認証対象のクライアントが利用要求を出しているクライアント ID です
  - クライアントが指定しない場合は入ってきません
- bundle_id- **この項目はオプションです**
  - 認証対象のコネクションが利用要求を出しているバンドル ID です
  - クライアントが指定しない場合は入ってきません
- connection_id- Base32-UUIDv4 です
  - 認証対象のコネクションに割り当てられたユニークな ID です
- channel_connections- 現在そのチャネルの接続数です
  - 自分は含まれません
- channel_sendrecv_connections- 現在そのチャネルで送受信をしている配信者の接続数です
  - 自分は含まれません
- channel_sendonly_connections- 現在そのチャネルで送信のみをしている配信者の接続数です
  - 自分は含まれません
- channel_recvonly_connections- 現在そのチャネルの配信を受信のみしている視聴者の接続数です
  - 自分は含まれません
- audio- `true` または `false` が入ってきます
  - `false` の場合は `audio` を使用しません
- audio_codec_type- **この項目はオプションです**
  - `audio` が `false` の場合は含まれません
  - コーデックはクライアントが送ってこない場合はデフォルトで `OPUS` が使用されます
  - コーデックの種類は `OPUS` のみです
- audio_bit_rate- **この項目はオプションです**
  - `audio` が `false` やクライアントが送ってこない場合、含まれません
  - この設定は `audio_codec_type` が `OPUS` の時のみ有効です
  - [default_audio_bit_rate](SORA_CONF.html#07627a) に値を指定していた場合はその値が利用されます
  - 最小が 6 で、最大が 510 です
  - 単位は `kbps` です
- video- `true` または `false` が入ってきます
  - `false` の場合は `video` を使用しません
- video_codec_type- **この項目はオプションです**
  - `video` が `false` の場合は含まれません
  - コーデックはクライアントが送ってこない場合はデフォルトで `VP9` が使用されます
  - コーデックの種類は `VP8`、 `VP9`、 `AV1`、 `H264`、 `H265` です
- video_bit_rate- **この項目はオプションです**
  - `video` が `false` の場合は含まれません
  - ビットレートはクライアントが送ってこない場合は `sora.conf` の [default_video_bit_rate](SORA_CONF.html#620132) が使用されます
  - デフォルトは 500 です
  - 最小が 1 で、最大が 30000 です
  - 15000 より大きい値は現時点でサポート範囲外です
  - 単位は `kbps` です
- video_vp9_params- **この項目はオプションです**
  - `video_codec_type` が `VP9` の場合に含まれます
  - 配信者が利用するビデオの VP9 の設定がオブジェクトとして入ってきます
  - 詳細は [ビデオの VP9 設定指定](WEBSOCKET_SIGNALING.html#b7556a) も参考にしてください
  - クライアントが `profile_id` の値を送ってこない場合は `sora.conf` の [default_vp9_param_profile_id](SORA_CONF.html#ab0de9) の値が使用されます
- video_av1_params- **この項目はオプションです**
  - `video_codec_type` が `AV1` の場合に含まれます
  - 配信者が利用するビデオの AV1 の設定がオブジェクトとして入ってきます
  - 詳細は [ビデオの AV1 設定指定](WEBSOCKET_SIGNALING.html#48f92d) も参考にしてください
  - クライアントが `profile` の値を送ってこない場合は `sora.conf` の [default_av1_param_profile](SORA_CONF.html#319e30) の値が使用されます
- video_h264_params- **この項目はオプションです**
  - `video_codec_type` が `H264` の場合に含まれます
  - 配信者が利用するビデオの H264 の設定がオブジェクトとして入ってきます
  - 詳細は [ビデオの H.264 設定指定](WEBSOCKET_SIGNALING.html#ffc4cb) も参考にしてください
  - クライアントが `profile_level_id` の値を送ってこない場合は `sora.conf` の [default_h264_param_profile_level_id](SORA_CONF.html#1581db) の値が使用されます
  - `b_frame` は `sora.conf` の [h264_b_frame](SORA_CONF.html#f546aa) が `true` のときに含まれます
  - クライアントが `b_frame` の値を送ってこない場合の値は `false` です
- video_h265_params- **この項目はオプションです**
  - `video_codec_type` が `H265` の場合に含まれます
  - 配信者が利用するビデオの H265 の設定がオブジェクトとして入ってきます
  - 詳細は [ビデオの H.265 設定指定](WEBSOCKET_SIGNALING.html#bfe45b) も参考にしてください
  - クライアントが `level_id` の値を送ってこない場合は `sora.conf` の [default_h265_param_level_id](SORA_CONF.html#d15808) の値が使用されます
  - `b_frame` は `sora.conf` の [h265_b_frame](SORA_CONF.html#a9a8f8) が `true` のときに含まれます
  - クライアントが `b_frame` の値を送ってこない場合の値は `false` です
- metadata- **この項目はオプションです**
  - ユーザーが定義を自由にできる値です
  - JSON で使用できる形式ならどんな値でも指定できます
  - `"type": "connect"` で `metadata` が送られてこない場合、アプリケーション側にも送られません
- authn_metadata- **この項目はオプションです**
  - この項目は metadata と同じです
  - metadata の別名です
  - `"type": "connect"` で `metadata` が送られてこない場合、アプリケーション側にも送られません
- data_channel_signaling- シグナリングの DataChannel 切り替えをするかどうか
- ignore_disconnect_websocket- シグナリングの DataChannel 切り替え時に WebSocket の切断を無視するかどうか
- data_channels- **この項目はオプションです**
  - DataChannel を利用したメッセージングの定義が入ってきます
- forwarding_filters- **この項目はオプションです**
  - 転送フィルターのリストが入ってきます
  - クライアントが指定しない場合は入ってきません
- sora_client- **この項目はオプションです**
  - クライアントから送られてきた情報が入ってきます
- duplicate_client- **この項目はオプションです**
  - クライアント ID 重複時の既存接続の追い出し機能が有効なセッションの認証ウェブフックに、既に重複する `client_id` のコネクションが存在する場合、そのクライアントの `ice_connection_state` が含まれます
  - `{"duplicate_client": {"ice_connection_state": "disconnected"}}` のような形式で返されます
  - シグナリング接続時に指定した `client_id` と重複する `client_id` のコネクションが存在する場合のみ含まれます


## 認証ウェブフックに含まれる同時接続数について

> **重要**
>
> 認証ウェブフックで送られてくる同時接続数、そのウェブフックが送られたタイミングの値であり、
> 厳密にそのチャネルの同時接続数を制限する値としては利用できません。

- channel_connections
- channel_sendrecv_connections
- channel_sendonly_connections
- channel_recvonly_connections

これら認証ウェブフックに含まれる同時接続数は WebRTC が確立した後に +1 され、WebRTC が切断されたタイミングで -1 されます。
そのため認証タイミングと WebRTC 確立時の時間差が存在します。

さらに、認証ウェブフックは並列で処理されるため、アプリ側でこの同時接続数の値を利用した厳密な同時接続数の制限を行うことはできません。

もし厳密なチャネル単位での同時接続数を制限したい場合は、
イベントウェブフック [connection.created](EVENT_WEBHOOK.html#eef06c) を利用して、
アプリ側でデータベースでロックを取ってカウントを行い、ロックを取って数値をチェックして認証を行ってください。

## sora_client

認証ウェブフックの `sora_client` にはクライアントから送られてきた情報が入ってきます。
クライアントから情報が送られてこなければ含まれません。 Sora SDK を利用している場合は必ず入ってきます。

```javascript
"sora_client": {
  "environment": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36",
  "raw": "Sora JavaScript SDK 2021.1.0",
  "type": "Sora JavaScript SDK",
  "version": "2023.2.0"
},
```

- type- オプションです
  - クライアントから送られてきた Sora SDK またはクライアントのタイプが入ってきます
- raw- オプションです
  - クライアントから送られてきた sora_client の値がそのまま入ってきます
- version- オプションです
  - クライアントから送られてきた Sora SDK またはクライアントのバージョンが入ってきます
- commit_short- オプションです
  - クライアントから送られてきた Sora SDK のコミットハッシュが入ってきます
- environment- オプションです
  - クライアントから送られてきた端末情報が入ってきます
- libwebrtc- オプションです
  - クライアントから送られてきた libwebrtc のバージョン情報が入ってきます

## 認証成功時のレスポンス JSON

認証に成功した場合は、以下の JSON をステータスコード 200 番台で返してください。

```javascript
{
  "allowed": true
}
```

Sora は `"allowed"` が `true` の場合は認証を成功と判断して処理をします。

### 認証成功時の払い出し項目

認証成功時に様々な項目を払い出すことができます。

詳細は [認証ウェブフック成功時の払い出し](AUTH_WEBHOOK_RETURN.html) をご確認ください。

## 認証失敗時のレスポンス JSON

認証に失敗した場合は、以下の JSON を返してください。

```javascript
{
  "allowed": false,
  "reason": "<String>"
}
```

> **注釈**
>
> 認証失敗の場合も HTTP レスポンスのステータスコードは 200 番台である必要があります

Sora は `"allowed"` が `false` で、 `"reason"` が含まれている場合に認証失敗と判断して処理します。

`"reason"` は必須です。何かしらエラー理由を **100 バイト以内** の文字列で指定してください。

認証に失敗した場合、認証サーバーから送られてきた `"reason"` の内容は、
WebSocket シグナリング切断時のメッセージとしてクライアントに送られます。

### 例

認証ウェブフックの戻り値で `"reason"` に `"REJECT"` を返した場合、
WebSocket シグナリング切断時のメッセージの `"reason"` に `"REJECT"` が含まれます。

#### 認証ウェブフックの戻り値

```javascript
{
  "allowed": false,
  "reason": "REJECT"
}
```

#### WebSocket シグナリング切断時のメッセージ

- `"code"` が `4490`
- `"reason"` が `"REJECT"`

## 認証ウェブフック成功時の払い出し

認証サーバーは認証成功時に様々な値を出すことができます。

```javascript
{
  "allowed": true,
  "event_metadata": {
    "pk": 1
  }
}
```

詳細は [認証ウェブフック成功時の払い出し](AUTH_WEBHOOK_RETURN.html) をご確認ください。


## WebSocket シグナリング時の HTTP ヘッダーを認証ウェブフックにコピーする機能

`sora.conf` の [copy_websocket_signaling_header_names](SORA_CONF.html#db39f3) を設定することで、
認証ウェブフックの HTTP ヘッダーに WebSocket シグナリング時の HTTP ヘッダーをコピーすることができます。

```ini
copy_websocket_signaling_header_names = X-Forwarded-For, X-Real-IP, Tracestate
```

> **危険**
>
> この機能は指定された WebSocket シグナリング時の HTTP ヘッダーを **そのままコピー** して認証ウェブフックに送信します。
> そのため、指定されたヘッダー名や、実際のヘッダー値に何が含まれていても何も検証は行いません。注意して利用してください。


## 認証ウェブフックログ

`sora.conf` の [auth_webhook_log](SORA_CONF.html#116686) を `true` にしている場合は `log/auth_webhook.jsonl` が出力されます。

> **重要**
>
> `auth_webhook_log` はデフォルトで `true` です。

このログには認証ウェブフックのリクエストとレスポンス、ウェブフック URL、タイムスタンプが含まれます。

- req- 認証ウェブフックの送信リクエストがそのまま入ります
- res- 認証ウェブフックの戻り値がそのまま入ります
- url- auth_webhook_url を指定していない場合はログに含まれません
- timestamp- RFC3339 フォーマットのタイムスタンプが入ります
  - UTC です
  - マイクロ秒まで含まれています
- copy_headers- [copy_websocket_signaling_header_names](SORA_CONF.html#db39f3) でコピーされた HTTP ヘッダーが入ります

### auth_webhook_url あり / レスポンスあり

```javascript
{
  "req": {
    "audio": true,
    "audio_codec_type": "OPUS",
    "channel_connections": 0,
    "channel_id": "sora",
    "channel_recvonly_connections": 0,
    "channel_sendonly_connections": 0,
    "channel_sendrecv_connections": 0,
    "connection_id": "F2SMT1W59S5ADDZ84CMQ8CDBX4",
    "e2ee": false,
    "label": "WebRTC SFU Sora",
    "node_name": "node1@192.0.2.10",
    "role": "sendrecv",
    "simulcast": false,
    "sora_client": {
      "environment": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
      "raw": "Sora JavaScript SDK 2020.5.0",
      "type": "Sora JavaScript SDK",
      "version": "2023.2.0"
    },
    "spotlight": false,
    "timestamp": "2020-12-07T09:16:54.079650Z",
    "version": "2024.1.0",
    "video": true,
    "video_bit_rate": 1000,
    "video_codec_type": "VP9",
    "video_vp9_params": { "profile_id": 0 }
  },
  "res": {
    "allowed": true,
    "event_metadata": {
      "abc": "efg"
    },
    "metadata": "abc",
    "signaling_notify_metadata": {
      "a": "b"
    }
  },
  "timestamp": "2020-12-07T09:16:54.089962Z",
  "url": "http://127.0.0.1:3001/sora/auth/webhook"
}
```

### auth_webhook_url あり / レスポンスなし

- res がありません

```javascript
{
  "req": {
    "audio": true,
    "audio_codec_type": "OPUS",
    "channel_connections": 0,
    "channel_id": "sora",
    "channel_recvonly_connections": 0,
    "channel_sendonly_connections": 0,
    "channel_sendrecv_connections": 0,
    "connection_id": "0FBC8HF84544ZDHYYN9BCRNZG8",
    "e2ee": false,
    "label": "WebRTC SFU Sora",
    "node_name": "node1@192.0.2.10",
    "role": "sendrecv",
    "simulcast": false,
    "sora_client": {
      "environment": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
      "raw": "Sora JavaScript SDK 2020.5.0",
      "type": "Sora JavaScript SDK",
      "version": "2023.2.0"
    },
    "spotlight": false,
    "timestamp": "2020-12-07T06:30:56.240917Z",
    "version": "2024.1.0",
    "video": true,
    "video_bit_rate": 1000,
    "video_codec_type": "VP9",
    "video_vp9_params": { "profile_id": 0 }
  },
  "timestamp": "2020-12-07T06:30:56.252785Z",
  "url": "http://127.0.0.1:3001/sora/authn/webhook"
}
```

### auth_webhook_url なし

- url がありません

```javascript
{
  "req": {
    "audio": true,
    "audio_codec_type": "OPUS",
    "channel_connections": 0,
    "channel_id": "sora",
    "channel_recvonly_connections": 0,
    "channel_sendonly_connections": 0,
    "channel_sendrecv_connections": 0,
    "client_id": "K8PCW533MN1WK24YNZ83HDP74C",
    "connection_id": "K8PCW533MN1WK24YNZ83HDP74C",
    "e2ee": false,
    "label": "WebRTC SFU Sora",
    "node_name": "node1@192.0.2.10",
    "role": "sendrecv",
    "simulcast": false,
    "sora_client": {
      "environment": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
      "raw": "Sora JavaScript SDK 2020.5.0",
      "type": "Sora JavaScript SDK",
      "version": "2023.2.0"
    },
    "spotlight": false,
    "timestamp": "2020-12-07T06:26:58.916204Z",
    "version": "2024.1.0",
    "video": true,
    "video_bit_rate": 1000,
    "video_codec_type": "VP9",
    "video_vp9_params": { "profile_id": 0 }
  },
  "res": {
    "allowed": true
  },
  "timestamp": "2020-12-07T06:26:58.916242Z"
}
```


## クラスターリレー機能利用時に認証が 2 回行われる場合がある

クラスターリレー機能を有効にしている場合、1 クライアントへの認証が **2 回** 行われる場合があります。

特定のノードに同時接続素の寄せを発生させるアフィニティ機能は認証成功時の払い出しで有効か無効かを指定できるため、
リレー機能が存在する場合はアフィニティの確認をするために必ず認証を行います。

その後、アフィニティが有効だったり、ライセンス上限に達していた場合で、別ノードへのリダイレクトが行われた場合、
リダイレクト先のノードで再度認証が発生します。

### アフィニティが有効で、アフィニティが発生し接続したノードにセッションが存在しない場合

クラスター全体のライセンスに余裕があれば、
既にセッションがある別ノードへリダイレクトを行い、再度認証を行います。

### アフィニティが有効で、かつ [cluster_affinity_threshold](SORA_CONF.html#2abc6a) の値を超えた場合

クラスター全体のライセンスに余裕があれば、
別ノードへリダイレクトを行い、再度認証を行います。

### アフィニティ関係なく、接続先ノードのライセンス上限の場合

クラスター全体でライセンスの上限に達していない場合、
別ノードへリダイレクトを行い、再度認証を行います。

## エラーメッセージ

これらエラーメッセージは sora.jsonl に出力されます。

### AUTH-WEBHOOK-RESPONSE-UNEXPECTED-STATUS-CODE

認証サーバーが返すステータスコードが 200 系ではなかった場合に出力されます。

例えばステータスコードが 400 だと出力されます。

### INVALID-AUTH-WEBHOOK-RESPONSE-JSON

認証サーバーが返す JSON に必須で項目が含まれていない場合に出力されます。

例えば `allowed` が含まれていない場合に出力されます。

### AUTH-WEBHOOK-RESPONSE-BAD-JSON

認証サーバーが返す JSON のデコードに失敗した場合に出力されます。

例えば `{"a: b"}` といったような JSON と判断できない場合に出力されます。

### AUTH-WEBHOOK-RESPONSE-EMPTY-BODY

認証サーバーがステータスコードが 200 系で空のボディを返した場合に出力されます。


## シーケンス図


### 認証成功

```mermaid
sequenceDiagram
    autonumber
    participant C as クライアント
    participant S as Sora
    participant A as アプリケーションサーバー
    C->>+S: "type": "connect"
    S->>+A: 認証ウェブフック
    A-->>-S: 200OK<br />{"allowed": true}
    S-->>-C: "type": "offer"
    C->>S: "type": "answer"
    note over C,A: WebRTC 確立
```


### 認証拒否

```mermaid
sequenceDiagram
    autonumber
    participant C as クライアント
    participant S as Sora
    participant A as アプリケーションサーバー
    C->>+S: "type": "connect"
    S->>+A: 認証ウェブフック
    A-->>-S: 200OK<br />{"allowed": false, "reason": "REJECT"}
    S->>C: WebSocket Close<br/>"code": 4490<br/>"reason": "REJECT"
```
