# MySQL 認証

拡張認証では、MySQL 統合によるパスワード認証をサポートしています。

::: tip 注意

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

:::

## テーブル構造とクエリ文

MySQL 認証機能は、複数テーブルの結合クエリやビューからのクエリなど、任意のテーブル構造をサポートします。ユーザーはクエリの SQL テンプレートを提供し、クエリ結果に以下のフィールドが含まれることを保証する必要があります。

- `password_hash`：必須。データベース内の平文またはハッシュ化されたパスワードフィールド。
- `salt`：任意。空または存在しない場合は空のソルト（salt = ""）とみなされます。
- `is_superuser`：任意。現在のクライアントがスーパーユーザーかどうかを示します。デフォルトは `false` です。**`true` に設定すると、そのユーザー名を使用するクライアントは認可制約を受けません。スーパーユーザーの設定は推奨されません。**

テーブル構造の例：

```sql
CREATE TABLE `mqtt_user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL,
  `password_hash` varchar(100) DEFAULT NULL,
  `salt` varchar(35) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `mqtt_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```

::: tip

上記の例では、クエリを支援するために暗黙の `UNIQUE` インデックスフィールド（`username`）を作成しています。ユーザー数が多いシステムでは、クエリに使用するテーブルが最適化され、有効なインデックスを使用していることを確認し、多数の接続時にデータ検索を高速化し EMQX の負荷を軽減してください。

:::

このテーブルでは `username` を検索条件として使用します。例えば、ユーザー名 `emqx_u`、パスワード `public`、ソルト `slat_foo123`、ハッシュ方式 `sha256`、スーパーユーザーフラグ `false` のユーザーを追加する場合：

```sql
mysql> INSERT INTO mqtt_user(username, password_hash, salt, is_superuser) VALUES ('emqx_u', SHA2(concat('public', 'slat_foo123'), 256), 'slat_foo123', 0);
Query OK, 1 row affected (0.01 sec)
```

対応するクエリ文およびパスワードハッシュ方式の設定パラメータは以下の通りです。

- パスワード暗号化方式：`sha256`
- ソルトモード：`suffix`
- SQL：

```sql
SELECT password_hash, salt, is_superuser FROM mqtt_user WHERE username = ${username} LIMIT 1
```

## MySQL 認証の設定

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

以下の関連設定を行ってください。

- **サーバー**：MySQL サーバーのアドレス（host:port）を入力します。

  ::: tip

  - 現在のデプロイメントが Dedicated エディションの場合は、[VPC ピアリング接続](./vpc_peering.md)を作成し、内部ネットワークアドレスをサーバーアドレスとして使用してください。
  - 現在のデプロイメントが BYOC エディションの場合は、パブリッククラウドコンソールで VPC ピアリング接続を作成してください。詳細は [VPC ピアリング接続の作成](./byoc_vpc_peering.md) を参照し、内部ネットワークアドレスをサーバーアドレスとして使用してください。
  - 「Init resource failure!」というメッセージが表示された場合は、サーバーアドレスの正確性とセキュリティグループの開放状況を確認してください。

  :::

- **データベース**：MySQL のデータベース名を入力します。

- **ユーザー名**（任意）：ユーザー名を入力します。

- **パスワード**（任意）：パスワードを入力します。

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

- **コネクションプールサイズ**（任意）：EMQX ノードから MySQL データベースへの同時接続数を整数で指定します。デフォルト値は `8` です。

- **クエリタイムアウト**：接続のタイムアウト時間を入力します。単位は時間、分、秒、ミリ秒が選択可能です。

- **パスワードハッシュ**：パスワード保存に使用するハッシュアルゴリズムを選択します。例：plain、md5、sha、bcrypt、pbkdf2 など。
  - `plain`、`md5`、`sha`、`sha256`、`sha512` の場合は、以下の設定も必要です。
    - **ソルト位置**：ソルトをパスワードに結合する方法を指定します。外部ストレージから EMQX 内蔵データベースへの認証情報移行を除き、通常は変更不要です。選択肢は suffix（パスワードの末尾にソルトを追加）、prefix（パスワードの先頭にソルトを追加）、disable（ソルトを使用しない）です。なお、plain を選択した場合はソルトモードを disable に設定してください。
  - `pbkdf2` アルゴリズムの場合は、以下の設定も必要です。
    - **疑似乱数関数**：キー生成に使用するハッシュ関数を指定します。例：sha256。
    - **反復回数**：ハッシュの繰り返し回数を指定します。デフォルトは 4096。
    - **派生キー長**（任意）：生成するキーの長さを指定します。指定しない場合は疑似乱数関数により決定されます。

- **SQL**：テーブル構造に応じたクエリ SQL を入力してください。詳細は [SQL テーブル構造とクエリ文](https://docs.emqx.com/en/enterprise/latest/access-control/authn/mysql.html#sql-table-structure-and-query-statements) を参照してください。
