このトピックでは、OpenSearch API V3 の署名方法と OpenSearch API V3 の使用方法について説明します。
OpenSearch は、各アクセスリクエストを認証します。 このサービスは、AccessKey ペアに基づく対称暗号化を実装して、ユーザーの ID を検証します。 各 AccessKey ペアは、AccessKey ID と AccessKey シークレットで構成されます。
AccessKey ID と AccessKey シークレットは、Alibaba Cloud によってユーザーに正式に発行されます。 Alibaba Cloud 国際サイト (alibabacloud.com) で AccessKey ペアをリクエストおよび管理できます。 AccessKey ID は、ユーザー ID を検証するために使用されます。
AccessKey シークレットは、署名文字列を暗号化し、サーバー上で署名文字列を検証するために使用されます。 AccessKey シークレットは厳重に管理する必要があります。
サポートされているアプリケーション
高度なアプリケーション
標準アプリケーション
プロトコル
OpenSearch API V3 は、HTTP プロトコルのみをサポートしています。
リクエストメソッド
データを検索するには、HTTP GET リクエストを送信する必要があります。
データを送信するには、HTTP POST リクエストを送信する必要があります。
Authorization ヘッダーの値を計算する
HTTP リクエストの Authorization ヘッダーに署名文字列を追加する必要があります。 これは、リクエストが認証されていることを示します。 HTTP リクエストには、他の必要なヘッダーも含まれている必要があります。 このトピックの「例」セクションでは、ヘッダーの例を示します。
Content-Md5、Content-Type、Date、OpenSearch 固有の HTTP ヘッダーなど、すべてのリクエストヘッダーは、署名計算に使用する必要があります。後続の署名対象文字列の「Authorization:OPENSEARCH 」にある OPENSEARCH の後には、スペースを追加する必要があります。
"Authorization: OPENSEARCH " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
VERB + "\n"
+ Content-Md5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedOpenSearchHeaders
+ CanonicalizedResource))
// 署名文字列の計算式
RFC 2104 で定義されている string-to-sign の HMAC 値を計算する
RFC 2104 で定義されている HMAC-SHA1 メソッドを使用して、署名文字列を計算します。
署名文字列は UTF-8 でエンコードする必要があります。
中国語の文字を含む署名文字列は、最初に UTF-8 でエンコードする必要があります。 エンコードされた署名文字列は、AccessKeySecret パラメーターと共に使用されて、最終的な署名文字列が計算されます。
署名文字列の計算に使用されるパラメーターは、上記のサンプルコードと同じ方法でソートする必要があります。
パラメーター | 説明 |
AccessKeyId | 必須。 リクエストを送信するユーザーの AccessKey ID。 このパラメーターは、Authorization ヘッダーに指定する必要があります。 |
AccessKeySecret | 必須。 リクエストを送信するユーザーの AccessKey シークレット。 AccessKey シークレットは、署名文字列の暗号化と検証に使用されます。 |
VERB | 必須。 リクエストメソッド。 HTTP リクエストでサポートされているメソッドには、PUT、GET、POST、HEAD、DELETE があります。 API 操作によって異なるリクエストメソッドが必要です。 |
\n | 改行。 |
Content-MD5 | HTTP リクエストボディの MD5 値。 リクエストにボディがある場合、このパラメーターは必須です。 このパラメーターは、受信したリクエストの内容が送信されたリクエストの内容と同じであるかどうかを確認するために使用されます。 これにより、リクエストの有効性が保証されます。 例: データを検索するリクエストなど、ボディがないリクエストの場合は、このパラメーターを指定しないでください。 詳細については、「RFC 2616 Content-MD5」をご参照ください。 |
Content-Type | 例: |
Date | 必須。 リクエストが送信された時刻。 ISO 8601 標準の YYYY-MM-DDThh:mm:ssZ 形式で時刻を指定します。 時刻は UTC である必要があります。 例: |
CanonicalizedOpenSearchHeaders | 必須。 リクエストを区別するために使用される OpenSearch 固有の HTTP ヘッダー。 |
CanonicalizedResource | 必須。 リクエストのパス。 例: |
データを検索するリクエスト
リクエスト署名パラメーター | 必須 | リクエストヘッダー | 必須 |
AccessKeySecret | はい | Date | はい |
VERB | はい | X-Opensearch-Nonce | はい |
Date | はい | Authorization | はい |
x-opensearch-nonce | はい | ||
canonicalized_resource | はい |
リクエストヘッダーの値は、署名の計算に指定された値と同じである必要があります。
Content-Md5、Content-Type、Date、CanonicalizedOpenSearchHeaders、Authorization パラメーターをリクエストヘッダーとして追加することをお勧めします。 必要なリクエストヘッダーのみを指定すると、エラーが発生する可能性があります。
すべてのリクエストヘッダーは、署名の計算に使用される必要があります。
データを送信するリクエスト
リクエスト署名パラメーター | 必須 | リクエストヘッダー | 必須 |
AccessKeySecret | はい | Content-MD5 | はい |
VERB | はい | Date | はい |
Content-MD5 | はい | Authorization | はい |
Date | はい | ||
canonicalized_resource | はい |
リクエストヘッダーの値は、署名の計算に指定された値と同じである必要があります。
Content-Md5、Content-Type、Date、CanonicalizedOpenSearchHeaders、Authorization パラメーターをリクエストヘッダーとして追加することをお勧めします。 必要なリクエストヘッダーのみを指定すると、エラーが発生する可能性があります。
すべてのリクエストヘッダーは、署名の計算に使用される必要があります。
CanonicalizedOpenSearchHeaders 文字列を作成する
CanonicalizedOpenSearchHeaders パラメーターには、X-Opensearch-
で始まるすべての OpenSearch 固有の HTTP ヘッダーが含まれます。 他の HTTP ヘッダーはこのセクションには関係ありません。
X-Opensearch-
で始まる OpenSearch 固有の HTTP ヘッダーの値を指定します。 たとえば、完全な HTTP ヘッダーはX-Opensearch-Nonce : 1551089397451704
です。 ヘッダーの値 (例:1551089397451704
) は、10 桁のタイムスタンプと 100000 ~ 999999 の 6 桁のランダムな値で構成されます。次に、値が空の OpenSearch 固有の HTTP ヘッダーをすべて省略します。残りの OpenSearch 固有の HTTP ヘッダーをすべてアルファベット順にソートします。
ソートされた HTTP ヘッダーの名前の大文字を小文字に変換します。 たとえば、
X-Opensearch-Nonce : 1551089397451704
をx-opensearch-nonce : 1551089397451704
に変換します。各ヘッダーとその値の間の区切り文字の両側のスペースをすべて削除します。 たとえば、元の HTTP ヘッダーは
x-opensearch-nonce : 1551089397451704
です。 スペースが削除されると、HTTP ヘッダーはx-opensearch-nonce:1551089397451704
になります。各ヘッダーと値のペアを 1 つの項目と見なします。
\n
区切り文字を使用してすべての項目を連結し、最終的な CanonicalizedOpenSearchHeaders 文字列を作成します。\n
区切り文字は、最後の項目にも追加する必要があります。
データを検索する HTTP リクエストには、OpenSearch 固有の HTTP ヘッダーが含まれていない場合があります。 これらのヘッダーは署名の計算には使用されません。 この場合、「\n」区切り文字は不要であり、CanonicalizedOpenSearchHeaders 文字列を作成する必要はありません。 string-to-sign から CanonicalizedOpenSearchHeaders パラメーターを削除します。
リクエストのヘッダーに OpenSearch 固有の HTTP ヘッダーを追加する場合は、小文字で構成される変換後の形式でヘッダー名を指定しないでください。 元の形式を使用する必要があります。
CanonicalizedResource 文字列を作成する
署名文字列は UTF-8 でエンコードする必要があります。 中国語の文字を含む署名文字列は、最初に UTF-8 でエンコードする必要があります。 エンコードされた署名文字列は、AccessKeySecret パラメーターと共に使用されて、最終的な署名文字列が計算されます。
データを検索するリクエストの CanonicalizedResource 文字列の形式は、パス + ? + クエリです。
データを送信するリクエストの CanonicalizedResource 文字列の形式は、パスです。
パス文字列を作成する
パス文字列を作成するには、元の文字列をエンコードし、%2F
をスラッシュ (/
) に置き換え、app_schema_demo をアプリケーションの名前に置き換えます。 次のリストは、4 つの一般的なパス文字列を示しています。
データを検索するリクエストのパス文字列:
/v3/openapi/apps/app_schema_demo/search
。候補に基づいてデータを検索するリクエストのパス文字列:
/v3/openapi/suggestions/suggestion_name/actions/search
。アプリケーションを使用してデータを検索するリクエストのパス文字列:
/v3/openapi/apps/appid
. この場合、appid を検索に使用するアプリケーションの ID に置き換え、認証のために Authorization ヘッダーを指定する必要があります。 リクエストパラメーターを指定する必要はありません。データを送信するリクエストのパス文字列:
/v3/openapi/apps/app_schema_demo/tab/actions/bulk
. この場合、tab をアプリケーションでデータを受信するために使用するテーブルの名前に置き換える必要があります。
クエリ文字列を作成する
クエリ文字列はリクエストパラメーターで構成されます。 パラメーターはキーと値のペアの形式で指定されます。 CanonicalizedResource 文字列のクエリ文字列を作成するには、次の手順を実行します。
使用する各リクエストパラメーターに値を割り当て、値が空のリクエストパラメーターを省略します。 値が空のリクエストパラメーターは、署名の計算には使用されません。
リクエストパラメーターを、最初に
key
で、次にvalue
でアルファベット順にソートします。RFC 3986 標準に基づいて、リクエストパラメーターの
key
とvalue
をエンコードします。 次に、等号 (=
) を使用して、エンコードされた各リクエストパラメーターのキーと値を連結します。アンパサンド (
&
) を使用して、エンコードされたリクエストパラメーターを連結し、値をクエリ文字列として保存します。パス文字列とクエリ文字列を使用して、パス + ? + クエリの形式で最終的な CanonicalizedResource 文字列を作成します。 CanonicalizedResource 文字列の例:
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson
。CanonicalizedResource 文字列の例には、次のリクエストパラメーターとその値が含まれています。
fetch_fields=name
CanonicalizedResource 文字列の例には、次のクエリパラメーターと句が含まれています。 最初の部分はクエリパラメーターを示し、2 番目の部分はクエリ句とその他の関連句を示します。
query=query=name:'document'&&sort=id&&config=format:fulljson
クエリパラメーターの文字列をエンコードする前に、句を二重アンパサンド (&&) で連結する必要があります。 データを送信するリクエストを送信する場合は、パス文字列のみを CanonicalizedResource 文字列として使用する必要があります。
Authorization ヘッダーを作成する
Authorization ヘッダーの作成方法については、このトピックの「Authorization ヘッダーの値を計算する」セクションをご参照ください。 たとえば、ユーザーの AccessKey ID が LTAI****************
で、署名文字列が 1P7tfE
**** であるとします。 次の Python 3 コードの例は、Authorization ヘッダーを作成します。
headers['Authorization'] = 'OPENSEARCH ' + 'LTAI****************' + ':' + '1P7tfE****'
// Authorization ヘッダーの作成例
例
たとえば、リクエストのヘッダーとパラメーター、およびリクエストメソッドは次のように構成されます。
Authorization:
OPENSEARCH LTAI****************:1P7tfE
****.AccessKeySecret:
yourAccessKeySecret
.リクエストメソッド:
GET
.Content-MD5: サンプルリクエストはデータを検索するために使用されるため、このパラメーターは空のままです。
Content-Type:
application/json
.Date:
2019-02-25T10:09:57Z
.CanonicalizedOpenSearchHeaders:
x-opensearch-nonce:15510****1704
.CanonicalizedResource:
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson
.
リクエストヘッダー | 署名文字列の計算式 | 例 |
'Content-MD5': '','Content-Type': 'application/json','Authorization': 'OPENSEARCH | Signature = base64(hmac-sha1(AccessKeySecret,VERB + "\n"+ Content-Md5 + "\n"+ Content-Type + "\n"+ Date + "\n"+ CanonicalizedOpenSearchHeaders+ CanonicalizedResource)) | R0OGKs****,GET\n\napplication/json\n2019-02-25T10:09:57Z\nx-opensearch-nonce:1551089397451704\n/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson |
リクエストヘッダーの値は、署名の計算に指定された値と同じである必要があります。
署名文字列の計算例
この例では、HMAC 値と Base64 エンコード形式を使用して署名文字列を計算します。
Python 3 コードの例:
import hmac
import base64
signature_string = '\n'.join(['GET',
'',
'application/json',
'2019-02-25T10:09:57Z',
'x-opensearch-nonce:1551089397451704',
'/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson'])
signature_hmac = hmac.new('R0OGKs****'.encode('utf-8'), signature_string.encode('utf-8'), 'sha1')
signature = base64.b64encode(signature_hmac.digest())
// 署名文字列の計算例
たとえば、ユーザーの AccessKey シークレットが yourAccessKeySecret であるとします。 上記の計算方法を使用して計算された最終的な署名文字列は 1P7tfE**** です。
リクエスト文字列を作成する
リクエスト文字列の形式は、ホスト + CanonicalizedResource 文字列です。
HTTP リクエストの Authorization ヘッダーに署名文字列を追加する必要があります。 これは、リクエストが認証されていることを示します。 HTTP リクエストには、前のセクションで説明した他の必要なヘッダーも含まれている必要があります。 リクエスト文字列では、ホストは OpenSearch API のエンドポイントを指定します。
データを検索するリクエストのリクエスト文字列:
http://host/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%8E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson
。候補に基づいてデータを検索するリクエストのリクエスト文字列:
http://host/v3/openapi/apps/{appName}/suggest/{suggestName}/search?hits=10&query=%E6%A0%87%E9%A2%98
。アプリケーションを使用してデータを検索するリクエストのリクエスト文字列:
http://host/v3/openapi/apps/120001234
. この場合、appid を検索に使用するアプリケーションの ID (例: 120001234) に置き換え、認証のために Authorization ヘッダーを指定する必要があります。 リクエストパラメーターを指定する必要はありません。データを送信するリクエストのリクエスト文字列:
http://host/v3/openapi/apps/app_schema_demo/tab/actions/bulk
. 送信されるデータは、リクエストボディで指定する必要があります。
OpenSearch は、OpenSearch API V3 に基づいて、Java 用 SDK、PHP 用 SDK、Python 用 SDK、C# 用 SDK を提供しています。 PHP 用 SDK、Python 用 SDK、C# 用 SDK は、署名を計算するための OpenSearch API V3 のメソッドを実装しています。 これらのメソッドを直接使用できます。 また、PHP 用 SDK、Python 用 SDK、C# 用 SDK の署名計算のソースコードを参照して、他の言語で SDK を実装することもできます。
OpenSearch は、このトピックと公式 SDK のソースコードに基づいて実装された SDK を保守していません。 ユーザーはこれらの SDK を自分で保守する必要があります。
アプリケーションスキーマテンプレート
{
"name": "app_schema_demo", // アプリケーション名
"type": "standard", // アプリケーションの種類
"schema": {
"indexes": {
"search_fields": { // 検索フィールド
"id": {
"fields": [
"id"
]
},
"name": {
"fields": [
"name"
],
"analyzer": "chn_standard" // アナライザ
},
"phone": {
"fields": [
"phone"
],
"analyzer": "fuzzy" // アナライザ
},
"int_arr": {
"fields": [
"int_arr"
]
},
"literal_arr": {
"fields": [
"literal_arr"
]
},
"cate_id": {
"fields": [
"cate_id"
]
}
},
"filter_fields": [ // フィルターフィールド
"id",
"int_arr",
"literal_arr",
"float_arr",
"cate_id"
]
},
"tables": {
"tab": { // テーブル名
"name": "tab", // テーブル名
"fields": { // フィールド
"id": {
"name": "id", // フィールド名
"type": "INT", // フィールドの種類
"primary_key": true // 主キーかどうか
},
"name": {
"name": "name", // フィールド名
"type": "TEXT", // フィールドの種類
"primary_key": false // 主キーかどうか
},
"phone": {
"name": "phone", // フィールド名
"type": "SHORT_TEXT", // フィールドの種類
"primary_key": false // 主キーかどうか
},
"int_arr": {
"name": "int_arr", // フィールド名
"type": "INT_ARRAY", // フィールドの種類
"primary_key": false // 主キーかどうか
},
"literal_arr": {
"name": "literal_arr", // フィールド名
"type": "LITERAL_ARRAY", // フィールドの種類
"primary_key": false // 主キーかどうか
},
"float_arr": {
"name": "float_arr", // フィールド名
"type": "FLOAT_ARRAY", // フィールドの種類
"primary_key": false // 主キーかどうか
},
"cate_id": {
"name": "cate_id", // フィールド名
"type": "INT", // フィールドの種類
"primary_key": false // 主キーかどうか
}
},
"primary_table": true // プライマリテーブルかどうか
}
},
"route_field": null // ルートフィールド
},
"data_sources": [], // データソース
"first_ranks": {}, // ファーストランク
"second_ranks": {}, // セカンドランク
"summary": [], // サマリー
"fetch_fields": [ // 取得フィールド
"id",
"name",
"phone",
"int_arr",
"literal_arr",
"float_arr",
"cate_id"
],
"quota": { // クォータ
"qps": 6, // qps
"doc_size": 0.3 // ドキュメントサイズ
}
}