# HTTP認可

EMQXはHTTPアプリケーションに基づく認可をサポートしています。このシナリオでは、ユーザーは外部のHTTPアプリケーションをデータソースとして設定し、EMQXはHTTPサービスにリクエストを送信してHTTP APIから返されるデータに基づき認可結果を判定することで、複雑な認可ロジックを実現します。

::: tip 注意

HTTP認可はEMQX Serverlessのデプロイメントではサポートされていません。

:::

## HTTP認可の仕組み

認可プロセスはHTTP APIコールに似ており、EMQXはリクエストクライアントとして「API」の要件に従いHTTPサービスへリクエストを構築・送信します。HTTPサービスは「クライアント」の要件に従い結果を返す必要があります。

- レスポンスの`content-type`は`application/json`である必要があります。
- 認可結果はボディ内の`result`で示され、値は`allow`、`deny`、`ignore`のいずれかです。
- HTTPステータスコードが`204`の場合、認可結果はパブリッシュまたはサブスクライブを許可とみなします。
- `200`および`204`以外のHTTPステータスコードは`ignore`とみなします。例えばHTTPサービスが利用不可の場合などです。

レスポンス例：

```json
HTTP/1.1 200 OK
Headers: Content-Type: application/json
...
Body:
{
    "result": "allow" | "deny" | "ignore" // デフォルトは `"ignore"`
}
```

## HTTP認可の設定

デプロイメント画面で **アクセス制御** -> **認可** -> **拡張認可** をクリックし、**HTTP認可** を選択して **設定** をクリックします。

ID認可の場合、EMQXプラットフォームは現在のクライアント情報を用いてユーザーが設定した認可問い合わせリクエストを作成・送信し、HTTPサーバー側でクライアントの認可データを照会します。

以下の手順に従って関連設定を行ってください：

- **Method**：HTTPリクエストメソッドを選択します。選択肢は`get`、`post`です。

  ::: tip

  `POST`メソッドの使用を推奨します。`GET`メソッドを使用すると、平文パスワードなどの一部の機密情報がHTTPサーバーログに露出する可能性があります。また、信頼できない環境ではHTTPSを使用してください。

  :::

- **URL**：HTTPサービスのURLアドレスを入力します。

  - URLは`http://`または`https://`で始まる必要があります。
  - ドメイン名にプレースホルダーを使用しないでください。
  - URLパス内で以下のプレースホルダーを使用できます：
    - `${clientid}`
    - `${username}`
    - `${password}`
    - `${peerhost}`
    - `${cert_subject}`
    - `${cert_common_name}`

- **Headers**（任意）：HTTPリクエストヘッダーの設定。複数のヘッダーを追加可能です。接続設定では、同時接続数、接続タイムアウト待機時間、最大HTTPリクエスト数、リクエストタイムアウト時間を設定します。

- **Enable TLS**：TLSを有効にするかどうかを設定します。

- **Connection Pool size**（任意）：EMQXノードから外部HTTPサーバーへの同時接続数を整数で指定します。デフォルト値は`8`です。

- **Connection Timeout**（任意）：接続タイムアウト時間を入力します。単位は時間、分、秒、ミリ秒が利用可能です。

- **HTTP Pipelining**（任意）：レスポンスを待たずに送信可能な最大HTTPリクエスト数を正の整数で指定します。デフォルト値は`100`です。

- **Request Timeout**（任意）：リクエストタイムアウト時間を入力します。単位は時間、分、秒、ミリ秒が利用可能です。

- **Body**：リクエストテンプレート。`POST`リクエストはJSON形式でリクエストボディに送信されます。`GET`リクエストはURLのクエリパラメータとしてエンコードされます。マッピングのキーと値にはプレースホルダーを使用可能です。

::: tip

- 現在のデプロイメントが専用版の場合、VPCピアリング接続を作成する必要があり、サーバーアドレスは内部ネットワークアドレスにしてください。
- 現在のデプロイメントがBYOC版の場合、パブリッククラウドコンソールでVPCピアリング接続を作成してください。詳細は[BYOCデプロイメントの作成 - VPCピアリング接続設定](../create/byoc.md#vpc-peering-connection-configuration)を参照してください。サーバーアドレスは内部ネットワークアドレスにしてください。
- 「Init resource failure!」が発生した場合、サーバーアドレスの正確性とセキュリティグループの開放状況を確認してください。

:::

## HTTPリクエストとレスポンス

クライアントがサブスクライブまたはパブリッシュ操作を開始すると、HTTP認可者は設定されたリクエストテンプレートに基づきリクエストを構築・送信します。リクエストテンプレート内で認可ロジックを実装し、必要な形式でチェック結果を返すようにしてください。

### リクエスト

リクエストはJSON形式を使用でき、URLおよびリクエストボディ内で以下のプレースホルダーが利用可能です：

- `${clientid}`：クライアントID
- `${username}`：クライアントがログイン時に使用したユーザー名
- `${peerhost}`：クライアントの送信元IPアドレス
- `${proto_name}`：クライアントが使用するプロトコル名（例：`MQTT`、`CoAP`）
- `${mountpoint}`：ゲートウェイリスナーのマウントポイント（トピックプレフィックス）
- `${action}`：要求されているアクション（例：`publish`、`subscribe`）
- `${topic}`：現在のリクエストでパブリッシュまたはサブスクライブされるトピック（またはトピックフィルター）
- `${qos}`：現在のリクエストでパブリッシュまたはサブスクライブされるメッセージのQoS
- `${retain}`：現在のリクエストでパブリッシュされるメッセージがリテインメッセージかどうか

### レスポンス

認可サービスは以下の形式でレスポンスを返す必要があります：

- レスポンスのcontent-typeは`application/json`である必要があります。
- HTTPステータスコードが200の場合、認可結果はHTTPボディの`result`フィールドの値により決定されます：
  - `allow`：パブリッシュまたはサブスクライブを許可
  - `deny`：パブリッシュまたはサブスクライブを拒否
  - `ignore`：このリクエストを無視し、次の認可者に処理を委ねる
- HTTPステータスコードが204の場合、このパブリッシュまたはサブスクライブリクエストは許可されたものとみなします。
- 200および204以外のHTTPステータスコードは「ignore」とみなします。例えばHTTPサービスが利用不可の場合など。

レスポンス例：

```
HTTP/1.1 200 OK
Headers: Content-Type: application/json
...
Body:
{
    "result": "allow" | "deny" | "ignore" // デフォルトは `"ignore"`
}
```

::: tip

`POST`メソッドの使用を推奨します。`GET`メソッドを使用すると、一部の機密情報がHTTPサーバーログに露出する可能性があります。

信頼できない環境ではHTTPSを使用してください。

:::
