メインコンテンツまでスキップ

高度なユーザー検索

Management API を直接利用して、高度なユーザー検索条件を活用できます。

検索リクエストの実行​

ユーザー検索には GET /api/users を使用します。これは他の Management API と同様に認証が必要です。操作方法は Management API との連携 を参照してください。

サンプル​

リクエスト

curl \
--location \
--request GET \
'http://<your-logto-endpoint>/api/users?search=%25alice%25'

レスポンス

User エンティティの配列が返されます。

[
{
"id": "MgUzzDsyX0iB",
"username": "alice_123",
"primaryEmail": "alice@some.email.domain",
"primaryPhone": null,
"name": null,
"avatar": null
// ...
}
]

パラメーター​

検索リクエストは以下のパラメーターキーで構成されます:

  • 検索キーワード: search, search.*
  • フィールドごとの検索モード: mode, mode.*(デフォルト値 'like'、利用可能な値 ['exact', 'like', 'similar_to', 'posix'])
  • 結合モード: joint または jointMode(デフォルト値 'or'、利用可能な値 ['or', 'and'])
  • 大文字小文字の区別: isCaseSensitive(デフォルト値 false)

この API には ページネーション が有効になっています。

いくつかの例を通して説明します。すべての検索パラメーターは URLSearchParams のコンストラクタ形式で記述します。

警告:

検索モードはデフォルトで like に設定されており、近似文字列検索(「あいまい検索」)が使われます。

注記:

すべてのあいまい検索モードは、各フィールドごとに 1 つの値のみ一致可能です。1 つのフィールドで複数の値を一致させたい場合は「exact」モードを使用してください。詳細は 完全一致と大文字小文字の区別 を参照してください。

すべての利用可能なフィールドであいまい検索を行いたい場合は、search キーに値を指定するだけです。内部的には the like operator が使われます:

new URLSearchParams([['search', '%foo%']]);

この検索は、ユーザー検索で利用可能なすべてのフィールド(id, primaryEmail, primaryPhone, username, name)を対象にします。

フィールドの指定​

例えば name のみで検索を限定したい場合、foo を名前に含むユーザーを検索するには、. 記号でフィールドを指定します:

new URLSearchParams([['search.name', '%foo%']]);

ネストされたフィールドはサポートされていません。例:search.name.first はエラーとなります。

複数のフィールドを同時に指定することも可能です:

new URLSearchParams([
['search.name', '%foo%'],
['search.primaryEmail', '%@gmail.com'],
]);

これは「名前に foo を含む」または「メールアドレスが @gmail.com で終わる」ユーザーを検索します。

結合モードの変更​

すべての条件を満たす結果のみ返したい場合は、結合モードを and に設定します:

new URLSearchParams([
['search.name', '%foo%'],
['search.primaryEmail', '%@gmail.com'],
['joint', 'and'],
]);

これは「名前に foo を含み」かつ「メールアドレスが @gmail.com で終わる」ユーザーを検索します。

完全一致と大文字小文字の区別​

例えば名前が正確に "Alice" のユーザーを検索したい場合、mode.name を exact に設定します。

new URLSearchParams([
['search.name', 'Alice'],
['mode.name', 'exact'],
]);

like モード(デフォルト)と exact を指定した場合で同じ効果が得られることもありますが、exact モードは比較に = を使い、like は like または ilike を使います。理論的には = の方がパフォーマンスが良いです。

さらに、exact モードでは複数の値を指定でき、それらは or で結合されます:

new URLSearchParams([
['search.name', 'Alice'],
['search.name', 'Bob'],
['mode.name', 'exact'],
]);

これは「名前が 'Alice'」または「'Bob'」のユーザーに一致します。

デフォルトでは検索は大文字小文字を区別しません。より厳密に検索したい場合は、isCaseSensitive を true に設定します:

new URLSearchParams([
['search.name', 'Alice'],
['search.name', 'Bob'],
['mode.name', 'exact'],
['isCaseSensitive', 'true'],
]);

isCaseSensitive はグローバル設定です。すべてのフィールドに適用されます。

正規表現 (RegEx)​

PostgreSQL は 2 種類の正規表現をサポートしています。similar to と posix です。mode を similar_to または posix に設定すると正規表現で検索できます:

new URLSearchParams([
['search', '^T.?m Scot+$'],
['mode', 'posix'],
]);

注意: similar_to モードは大文字小文字を区別する検索でのみ動作します。

マッチモードの上書き​

デフォルトでは、すべてのキーワードは一般検索のマッチモードを継承します:

new URLSearchParams([
['search', '^T.?m Scot+$'],
['mode', 'posix'],
['search.primaryEmail', 'tom%'], // Posix モード
['joint', 'and'],
]);

特定のフィールドのみ上書きしたい場合:

new URLSearchParams([
['search', '^T.?m Scot+$'],
['mode', 'posix'],
['search.primaryEmail', 'tom%'], // Like モード
['mode.primaryEmail', 'like'],
['search.phone', '0{3,}'], // Posix モード
['joint', 'and'],
]);

外部アイデンティティによる検索​

ソーシャルまたはエンタープライズ SSO アイデンティティに紐づくユーザーを検索するには、以下の 3 つのクエリパラメーターをすべて指定して完全一致検索を行います:

  • identityType: ソーシャルコネクターの場合は social、エンタープライズ SSO の場合は sso
  • identityProvider: ソーシャルアイデンティティの場合はコネクター名(例:dingtalk)、エンタープライズ SSO の場合は発行者
  • identityId: 外部アイデンティティプロバイダーが発行したユーザー識別子
// DingTalk ソーシャルアイデンティティに紐づくユーザーを検索
new URLSearchParams([
['identityType', 'social'],
['identityProvider', 'dingtalk'],
['identityId', 'dingtalk-open-id'],
]);
// エンタープライズ SSO アイデンティティに紐づくユーザーを検索
new URLSearchParams([
['identityType', 'sso'],
['identityProvider', 'https://example.com/issuer'],
['identityId', 'enterprise-user-id'],
]);

アイデンティティフィルターは他の検索フィルターと AND で組み合わされます。例えば、さらにキーワード検索で絞り込みたい場合:

new URLSearchParams([
['identityType', 'social'],
['identityProvider', 'dingtalk'],
['identityId', 'dingtalk-open-id'],
['search', '%foo%'],
]);

カスタムデータによる検索​

カスタムデータ に保存された値でユーザーを検索するには、1 つ以上の customData クエリパラメーターを GET /api/users に渡します。各値は URL エンコードされた JSON オブジェクトである必要があります:

curl \
--get \
--data-urlencode 'customData={"qq":114514}' \
'http://<your-logto-endpoint>/api/users'

--data-urlencode は JSON オブジェクトを自動でエンコードします。同等のリクエスト URL は GET /api/users?customData=%7B%22qq%22%3A114514%7D です。

注記:

カスタムデータ検索は、テナント内のユーザー数が多い場合は遅くなることがあります。customData と他の選択的なフィルター(search やアイデンティティ検索など)を組み合わせてクエリを絞り込んでください。

Logto はユーザーの custom_data に対して JSONB 包含 で値を照合します。値に含まれるキーのみ一致すればよく、ユーザーのカスタムデータ内の他のキーは無視されます。

  • 型は厳密です:数値 114514 は文字列 "114514" とは一致しません。
  • 文字列は大文字小文字を区別します。
  • null は明示的な JSON の null のみ一致し、キーが存在しない場合は一致しません。
  • ネストされたオブジェクトは再帰的に一致します。
  • 配列は順序や重複に関係なく要素単位で一致します。

1 つの JSON オブジェクト内のすべてのキーは AND で一致します。customData を複数回指定した場合、いずれかのオブジェクトが一致すればユーザーが一致します(OR):

curl \
--get \
--data-urlencode 'customData={"qq":114514}' \
--data-urlencode 'customData={"wechat":"logto"}' \
'http://<your-logto-endpoint>/api/users'

カスタムデータフィルターは、search、アイデンティティ検索(identityType、identityProvider、identityId)、excludeRoleId、excludeOrganizationId など他のフィルターとも常に AND で組み合わされます。例えば、次のリクエストは qq が 114514 かつ username に alice を含むユーザーを返します:

curl \
--get \
--data-urlencode 'customData={"qq":114514}' \
--data-urlencode 'search.username=%alice%' \
'http://<your-logto-endpoint>/api/users'

mode、joint、isCaseSensitive パラメーターはキーワード検索のみに影響し、customData には影響しません。

customData の値が有効な JSON オブジェクトでない場合(例:[] や 114514)、空オブジェクト {}、または任意の階層で空オブジェクトや空配列(例:{"profile":{}} や {"tags":[]})を含む場合、API は 400 Bad Request を返します。customData.qq、customData[qq]、mode.customData などのネストしたパラメーター名も 400 で拒否されます。