cvm.tencentcloudapi.com)をサポートしており、指定リージョンドメインアクセス(例:広州地域のドメインはcvm.ap-guangzhou.tencentcloudapi.com)もサポートしています。各リージョンのパラメータについては、共通パラメータのリージョンリストを参照してください。詳細は各製品の「リクエスト構造」ドキュメントで当該リージョンのサポート状況を確認してください。パラメータ名 | タイプ | 必須 | 説明 |
X-TC-Action | String | はい | 操作のAPI名。値はAPIドキュメントの入力パラメータの共通パラメータActionの説明を参照してください。例えばCVMのインスタンスリスト検索APIは、値がDescribeInstancesです。 |
X-TC-Region | String | - | リージョンパラメータは、操作対象となるデータのリージョンを識別するために使用されます。APIが受け入れるリージョンの値については、APIドキュメントの入力パラメータの共通パラメータRegionの説明を参照してください。注意:一部のAPIではこのパラメータの受け渡しが不要であり、APIドキュメントに特別な記載があります。その場合、パラメータを渡しても有効になりません。 |
X-TC-Timestamp | Integer | はい | 現在のUNIXタイムスタンプは、APIリクエストを開始した時間を記録できます。例えば、1529223702。注意:サーバー時間と5分以上の差がある場合、署名の期限切れエラーが発生します。 |
X-TC-Version | String | はい | 操作するAPIのバージョン。値をAPIドキュメントの入力パラメータの共通パラメータVersionの説明を参照してください。例えばCVMのバージョン2017-03-12です。 |
Authorization | String | はい | HTTP標準認証ヘッダーフィールド。例:TC3-HMAC-SHA256 Credential=AKIDEXAMPLE/Date/service/tc3_request, SignedHeaders=content-type;host, Signature=72e494ea8******************************************a96525168 ここで: TC3-HMAC-SHA256:署名方式であり、現在はこの値に固定されています。 Credential:署名の認証情報。AKIDEXAMPLEはSecretIdです。 DateはUTC標準時の日付であり、その値は共通パラメータX-TC-Timestampを変換したUTC標準時の日付と一致する必要があります。 serviceは製品名であり、通常はドメインのプレフィックスです。例えば、ドメイン cvm.tencentcloudapi.com は製品名が cvm であることを意味します。本製品の値は cvm です。 SignedHeaders:署名計算に参加するヘッダー情報であり、content-type と host は必須ヘッダーです。 Signature:署名ダイジェスト。計算プロセスの詳細は下記を参照してください。 |
X-TC-Token | String | いいえ | 一時的な証明書で使用されるTokenは、一時的なシークレットキーと組み合わせて使用する必要があります。一時的なシークレットキーとTokenは、CAMサービスでAPIを呼び出して取得する必要があります。長期シークレットキーにはTokenは不要です。 |
パラメータ名 | タイプ | 必須 | 説明 |
Action | String | はい | 操作するAPI名。値はAPIドキュメントの入力パラメータの共通パラメータActionの説明を参照してください。例えばCVMのインスタンスリストの表示APIの場合、値はDescribeInstancesです。 |
Region | String | - | リージョンパラメータは、操作対象となるデータのリージョンを識別するために使用されます。APIが受け入れるリージョンの値については、APIドキュメントの入力パラメータの共通パラメータRegionの説明を参照してください。注意:一部のAPIではこのパラメータの受け渡しが不要であり、APIドキュメントに特別な記載があります。その場合、パラメータを渡しても有効になりません。 |
Timestamp | Integer | はい | 現在のUNIXタイムスタンプは、APIリクエストを開始した時間を記録できます。例えば、1529223702。現在の時間と差が大きすぎる場合、署名の期限切れエラーが発生します。 |
Nonce | Integer | はい | ランダムな正の整数であり、Timestampと組み合わせてリプレイ攻撃を防止するために使用されます。 |
SecretId | String | はい | TencentCloud APIキーで申請されたIDを識別するSecretIdであり、一つのSecretIdは唯一のSecretKeyに対応します。SecretKeyはリクエストの署名Signatureを生成するために使用されます。 |
Signature | String | はい | リクエスト署名は、今回のリクエストの正当性を検証するために使用されます。ユーザーは実際の入力パラメータに基づいて計算する必要があります。具体的な計算方法については、下記の「署名方法の紹介」を参照してください。 |
Version | String | はい | 操作するAPIのバージョン。値をAPIドキュメントの入力パラメータの共通パラメータVersionの説明を参照してください。例えばCVMのバージョン2017-03-12です。 |
SignatureMethod | String | いいえ | 署名方式は、現在HmacSHA256とHmacSHA1をサポートしています。このパラメータをHmacSHA256に指定した場合のみ、HmacSHA256アルゴリズムを使用して署名を検証します。その他の場合はすべてHmacSHA1を使用して署名を検証します。 |
Token | String | いいえ | 一時的な証明書で使用されるTokenは、一時的なシークレットキーと組み合わせて使用する必要があります。一時的なシークレットキーとTokenは、CAMサービスでAPIを呼び出して取得する必要があります。長期シークレットキーにはTokenは不要です。 |
AKIDz8krbsJ5**********mLPx3EXAMPLE と Gu5t9xGAR***********EXAMPLEであると仮定します。ユーザーが広州リージョンのCVMで「未命名」という名前のホストステータスを確認したい場合、データを1件のみ返します。リクエストは次のようになります: curl -X POST https://cvm.tencentcloudapi.com \\-H "Authorization: TC3-HMAC-SHA256 Credential=AKIDz8krbsJ5**********mLPx3EXAMPLE/2019-02-25/cvm/tc3_request, SignedHeaders=content-type;host, Signature=72e494ea8******************************************a96525168" \\-H "Content-Type: application/json; charset=utf-8" \\-H "Host: cvm.tencentcloudapi.com" \\-H "X-TC-Action: DescribeInstances" \\-H "X-TC-Timestamp: 1551113065" \\-H "X-TC-Version: 2017-03-12" \\-H "X-TC-Region: ap-guangzhou" \\-d '{"Limit": 1, "Filters": [{"Values": ["\\u672a\\u547d\\u540d"], "Name": "instance-name"}]}'


CanonicalRequest =HTTPRequestMethod + '\\n' +CanonicalURI + '\\n' +CanonicalQueryString + '\\n' +CanonicalHeaders + '\\n' +SignedHeaders + '\\n' +HashedRequestPayload
フィールド名称 | 説明 |
HTTPRequestMethod | HTTPリクエスト方法(GET、POST)。このサンプルでは、値は POSTです。 |
CanonicalURI | URIパラメータは、API 3.0ではスラッシュ(/)に固定されます。 |
CanonicalQueryString | HTTPリクエストURLのクエリ文字列です。POSTリクエストの場合、空文字列""に固定されます。GETリクエストの場合、URL内の疑問符(?)以降の文字列内容となります(例:Limit=10&Offset=0)。注意:CanonicalQueryStringはRFC3986を参照してURLEncodeを行う必要があり、文字セットはUTF8です。プログラミング言語の標準ライブラリを使用することを推奨し、すべての特殊文字をエンコードし、大文字形式とします。 |
CanonicalHeaders | 署名に使用するヘッダー情報は、少なくともhostとcontent-typeの2つのヘッダーを含める必要があります。また、カスタムヘッダーを追加して署名に参加させることで、リクエストの一意性と安全性を高めることができます。
連結ルール:ヘッダーのkeyとvalueはすべて小文字に変換し、先頭と末尾のスペースを削除した後、key:value\\n の形式で連結します。複数のヘッダーがある場合は、ヘッダーのkey(小文字)のASCIIコードの昇順で連結します。
この例での計算結果は content-type:application/json; charset=utf-8\\nhost:cvm.tencentcloudapi.com\\nです。
注意:content-typeは実際に送信するものと一致している必要があります。一部のプログラミング言語のネットワークライブラリは、指定されていない場合でも自動的にcharset値を追加することがあります。署名時と送信時でcontent-typeが一致しない場合、サーバーは署名検証失敗を返します。 |
SignedHeaders | 署名に参加するヘッダー情報であり、今回のリクエストでどのヘッダーが署名に参加したかを説明します。CanonicalHeadersに含まれるヘッダー内容と一対一対応します。content-typeとhostは必須ヘッダーです。
連結ルール:ヘッダーのkeyはすべて小文字に変換します。複数のヘッダーkey(小文字)はASCII昇順で連結し、セミコロン(;)で区切ります。この例では、content-type;hostとなります。 |
HashedRequestPayload | リクエスト本文(Requestpayload、すなわちbodyです。この例では {"Limit": 1, "Filters": [{"Values": ["\\u672a\\u547d\\u540d"], "Name": "instance-name"}]})のハッシュ値です。計算の疑似コードは Lowercase(HexEncode(Hash.SHA256(RequestPayload))) であり、HTTPリクエスト本文に対してSHA256ハッシュを適用し、16進数エンコードした後、エンコード文字列を小文字に変換します。GETリクエストの場合、RequestPayloadは空文字列に固定されます。この例の計算結果は35e9c5b0e3ae67532d3c9f17ead6c90222632e5b1ff7f6e89887f1398934f064です。 |
POST/content-type:application/json; charset=utf-8host:cvm.tencentcloudapi.comcontent-type;host35e9c5b0e3ae67532d3c9f17ead6c90222632e5b1ff7f6e89887f1398934f064
StringToSign =Algorithm + \\n +RequestTimestamp + \\n +CredentialScope + \\n +HashedCanonicalRequest
フィールド名称 | 説明 |
Algorithm | 署名アルゴリズムは、現在 TC3-HMAC-SHA256に固定されています。 |
RequestTimestamp | リクエストタイムスタンプは、リクエストヘッダーの共通パラメータX-TC-Timestampの値であり、現在時刻のUNIXタイムスタンプを秒単位で取得したものです。このサンプルの値は 1551113065 です。 |
CredentialScope | クレデンシャルスコープの形式は Date/service/tc3_request であり、日付、リクエスト対象サービス、終端文字列(tc3_request)を含みます。Date は UTC標準時の日付であり、値は共通パラメータ X-TC-Timestamp から換算した UTC標準時の日付と一致する必要があります、service は製品名であり、呼び出す製品のドメイン名と一致しなければなりません。このサンプルの計算結果は 2019-02-25/cvm/tc3_request です。 |
HashedCanonicalRequest | 前述の手順で連結された正規リクエスト文字列のハッシュ値であり、計算の擬似コードは Lowercase(HexEncode(Hash.SHA256(CanonicalRequest))) です。このサンプルの計算結果は 5ffe6a04c0664d6b969fab9a13bdab201d63ee709638e2749d62a09ca18d7031 です。 |
TC3-HMAC-SHA25615511130652019-02-25/cvm/tc3_request5ffe6a04c0664d6b969fab9a13bdab201d63ee709638e2749d62a09ca18d7031
secretDate := hmacsha256(date, "TC3"+secretKey)secretService := hmacsha256(service, secretDate)secretSigning := hmacsha256("tc3_request", secretService)signature := hex.EncodeToString([]byte(hmacsha256(string2sign, secretSigning)))fmt.Println(signature)
SecretDate、SecretService および SecretSigning はバイナリデータであり、非印字文字を含む可能性があるため、ここでは中間結果を表示しません。フィールド名称 | 説明 |
secretKey | 元のsecretKey、すなわち Gu5t9xGAR***********EXAMPLE。 |
date | すなわち、Credential の Date フィールド情報(標準時間)です。このサンプルの値は 2019-02-25 です。 |
service | すなわちCredentialのServiceフィールドの情報です。この例の値は cvmです。 |
72e494ea8******************************************a96525168 です。authorization := fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s",algorithm,secretId,credentialScope,signedHeaders,signature)fmt.Println(authorization)
フィールド名称 | 説明 |
algorithm | 署名方法は TC3-HMAC-SHA256に固定されています。 |
secretId | キーペアのSecretId、すなわち AKIDz8krbsJ5**********mLPx3EXAMPLE。 |
credentialScope | 上記参照、クレデンシャルスコープです。このサンプルの計算結果は 2019-02-25/cvm/tc3_request です。 |
signedHeaders | 上記参照、署名に参加するヘッダー情報です。この例の値は content-type;hostです。 |
signature | シグネチャ値。この例の計算結果は 72e494ea8******************************************a96525168です。 |
TC3-HMAC-SHA256 Credential=AKIDz8krbsJ5**********mLPx3EXAMPLE/2019-02-25/cvm/tc3_request, SignedHeaders=content-type;host, Signature=72e494ea8******************************************a96525168
POST https://cvm.tencentcloudapi.com/Authorization: TC3-HMAC-SHA256 Credential=AKIDz8krbsJ5**********mLPx3EXAMPLE/2019-02-25/cvm/tc3_request, SignedHeaders=content-type;host, Signature=72e494ea8******************************************a96525168Content-Type: application/json; charset=utf-8Host: cvm.tencentcloudapi.comX-TC-Action: DescribeInstancesX-TC-Version: 2017-03-12X-TC-Timestamp: 1551113065X-TC-Region: ap-guangzhou{"Limit": 1, "Filters": [{"Values": ["\\u672a\\u547d\\u540d"], "Name": "instance-name"}]}
package mainimport ("crypto/hmac""crypto/sha256""encoding/hex""fmt""time")func sha256hex(s string) string {b := sha256.Sum256([]byte(s))return hex.EncodeToString(b[:])}func hmacsha256(s, key string) string {hashed := hmac.New(sha256.New, []byte(key))hashed.Write([]byte(s))return string(hashed.Sum(nil))}func main() {secretId := "AKIDz8krbsJ5**********mLPx3EXAMPLE"secretKey := "Gu5t9xGAR***********EXAMPLE"host := "cvm.tencentcloudapi.com"algorithm := "TC3-HMAC-SHA256"service := "cvm"version := "2017-03-12"action := "DescribeInstances"region := "ap-guangzhou"//var timestamp int64 = time.Now().Unix()var timestamp int64 = 1551113065// step 1: build canonical request stringhttpRequestMethod := "POST"canonicalURI := "/"canonicalQueryString := ""canonicalHeaders := "content-type:application/json; charset=utf-8\\n" + "host:" + host + "\\n"signedHeaders := "content-type;host"payload := `{"Limit": 1, "Filters": [{"Values": ["\\u672a\\u547d\\u540d"], "Name": "instance-name"}]}`hashedRequestPayload := sha256hex(payload)canonicalRequest := fmt.Sprintf("%s\\n%s\\n%s\\n%s\\n%s\\n%s",httpRequestMethod,canonicalURI,canonicalQueryString,canonicalHeaders,signedHeaders,hashedRequestPayload)fmt.Println(canonicalRequest)// step 2: build string to signdate := time.Unix(timestamp, 0).UTC().Format("2006-01-02")credentialScope := fmt.Sprintf("%s/%s/tc3_request", date, service)hashedCanonicalRequest := sha256hex(canonicalRequest)string2sign := fmt.Sprintf("%s\\n%d\\n%s\\n%s",algorithm,timestamp,credentialScope,hashedCanonicalRequest)fmt.Println(string2sign)// step 3: sign stringsecretDate := hmacsha256(date, "TC3"+secretKey)secretService := hmacsha256(service, secretDate)secretSigning := hmacsha256("tc3_request", secretService)signature := hex.EncodeToString([]byte(hmacsha256(string2sign, secretSigning)))fmt.Println(signature)// step 4: build authorizationauthorization := fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s",algorithm,secretId,credentialScope,signedHeaders,signature)fmt.Println(authorization)curl := fmt.Sprintf(`curl -X POST https://%s\\-H "Authorization: %s"\\-H "Content-Type: application/json; charset=utf-8"\\-H "Host: %s" -H "X-TC-Action: %s"\\-H "X-TC-Timestamp: %d"\\-H "X-TC-Version: %s"\\-H "X-TC-Region: %s"\\-d '%s'`, host, authorization, host, action, timestamp, version, region, payload)fmt.Println(curl)}
パラメータ名 | 中国語 | パラメータ値 |
Action | メソッド名 | DescribeInstances |
SecretId | シークレットキーID | AKIDz8krbsJ5**********mLPx3EXAMPLE |
Timestamp | 現在のタイムスタンプ | 1465185768 |
Nonce | ランダムな正の整数 | 11886 |
Region | インスタンスのリージョン | ap-guangzhou |
InstanceIds.0 | 照会対象インスタンスID | ins-09dx96dg |
Offset | オフセット | 0 |
Limit | 最大許容出力 | 20 |
Version | APIバージョン番号 | 2017-03-12 |
{'Action' : 'DescribeInstances','InstanceIds.0' : 'ins-09dx96dg','Limit' : 20,'Nonce' : 11886,'Offset' : 0,'Region' : 'ap-guangzhou','SecretId' : 'AKIDz8krbsJ5**********mLPx3EXAMPLE','Timestamp' : 1465185768,'Version': '2017-03-12',}
Action=DescribeInstances&InstanceIds.0=ins-09dx96dg&Limit=20&Nonce=11886&Offset=0&Region=ap-guangzhou&SecretId=AKIDz8krbsJ5**********mLPx3EXAMPLE&Timestamp=1465185768&Version=2017-03-12
cvm.tencentcloudapi.com。実際のリクエストドメインは、APIが属するモジュールによって異なります。詳細は各APIの説明を参照してください。リクエストメソッド + リクエストホスト + リクエストパス + ? + リクエスト文字列です。GETcvm.tencentcloudapi.com/?Action=DescribeInstances&InstanceIds.0=ins-09dx96dg&Limit=20&Nonce=11886&Offset=0&Region=ap-guangzhou&SecretId=AKIDz8krbsJ5**********mLPx3EXAMPLE&Timestamp=1465185768&Version=2017-03-12
hashed := hmac.New(sha1.New, []byte(secretKey))hashed.Write(buf.Bytes())fmt.Println(base64.StdEncoding.EncodeToString(hashed.Sum(nil)))
# 実際の呼び出しでは、成功した場合、消費型APIであれば課金が発生します(ここではPython言語を例としてgetリクエストを送信します)resp = requests.get("https://" + endpoint, params=data)print(resp.url)
最終的に得られるリクエスト文字列は次のようになります:https://cvm.tencentcloudapi.com/?Nonce=11886&SecretId=AKIDz8krbsJ5**********mLPx3EXAMPLE&Limit=20&Version=2017-03-12&Offset=0&Action=DescribeInstances&Timestamp=1465185768&Region=ap-guangzhou&Signature=EliP9YW3pW28FpsEdkXt%2F%2BWcGeI%3D&InstanceIds.0=ins-09dx96dg
フィールド名称 | 説明 |
endpoint | サービスアドレス、 例: cvm.tencentcloudapi.com |
data | API 3.0 署名 V1のサンプルAPIパラメータ。注意 ここでは計算された署名をキー値ペアの形式でdataに追加する必要があります。 |
Eli*****************cGeI= の場合、最終的に得られる署名文字列のリクエストパラメータ(Signature)は:EliP***********************eI%3D となり、これは最終的なリクエストURLの生成に使用されます。%XY 形式のパーセントエンコーディングを使用します。ここで X と Y は16進数文字(0-9および大文字のA-F)です。小文字を使用するとエラーが発生します。package mainimport ("bytes""crypto/hmac""crypto/sha1""encoding/base64""net/url""fmt""sort")func main() {secretId := "AKIDz8krbsJ5**********mLPx3EXAMPLE"secretKey := "Gu5t9xGAR***********EXAMPLE"endpoint := "cvm.tencentcloudapi.com"params := map[string]string{"Nonce": "11886","Timestamp": "1465185768","Region": "ap-guangzhou","SecretId": secretId,"Version": "2017-03-12","Action": "DescribeInstances","InstanceIds.0": "ins-09dx96dg","Limit": "20","Offset": "0",}var buf bytes.Bufferbuf.WriteString("GET")buf.WriteString(endpoint)buf.WriteString("/")buf.WriteString("?")// sort keys by ascii asc orderkeys := make([]string, 0, len(params))for k, _ := range params {keys = append(keys, k)}sort.Strings(keys)for i := range keys {k := keys[i]buf.WriteString(k)buf.WriteString("=")buf.WriteString(params[k])buf.WriteString("&")}buf.Truncate(buf.Len() - 1)hashed := hmac.New(sha1.New, []byte(secretKey))hashed.Write(buf.Bytes())signature := base64.StdEncoding.EncodeToString(hashed.Sum(nil))fmt.Println(base64.StdEncoding.EncodeToString(hashed.Sum(nil)))final_signature := url.QueryEscape(signature)fmt.Println(final_signature)}
エラーコード | エラー説明 |
AuthFailure.SignatureExpire | シグネチャの期限切れです。Timestampとサーバーがリクエストを受信した時間との差は5分を超えてはなりません。 |
AuthFailure.SecretIdNotFound | シークレットキーが存在しません。コンソールでキーが無効化されていないか、文字を少なくコピーしたか、あるいは多くコピーしたかを確認してください。 |
AuthFailure.SignatureFailure | シグネチャエラーです。シグネチャの計算エラー、またはシグネチャと実際に送信した内容が一致しない可能性があります。シークレットキー SecretKey のエラーによるものである可能性もあります。 |
AuthFailure.TokenFailure | 一時証明書Tokenエラーです。 |
AuthFailure.InvalidSecretId | シークレットキーが無効です(TencentCloud APIキータイプではありません)。 |
{"Response": {"TotalCount": 0,"InstanceStatusSet": [],"RequestId": "b5b41468-520d-4192-b42f-595cc34b6c1c"}}
Responseおよびその内部のRequestIdは固定のフィールドであり、リクエストが成功したかどうかに関わらず、APIが処理した限り、必ず返されます。RequestIdはAPIリクエストの唯一の識別子として使用されます。APIに異常が発生した場合は、該当 ID を添えて連絡してください。TotalCountとInstanceStatusSetはいずれもDescribeInstancesStatus APIスで定義されたフィールドです。リクエストを呼び出したユーザーが現在CVMインスタンスを保有していないため、TotalCountのこの状況での戻り値は0となり、InstanceStatusSetリストは空です。{"Response": {"Error": {"Code": "AuthFailure.SignatureFailure","Message": "The provided credentials could not be validated. Please check your signature is correct."},"RequestId": "ed93f3cb-f35e-473f-b9f3-0d451b8b79c6"}}
Errorが出現するということは、そのリクエストの呼び出しが失敗したことを表します。Errorフィールドは、その内部のCodeおよびMessageフィールドとともに、呼び出しが失敗した場合には必ず返されます。Codeは具体的なエラーコードを示し、リクエストがエラーになった場合、まずこのコードを使用して共通エラーコードリストおよび該当APIのエラーコードリストで原因と解決策を確認できます。Messageはこのエラーが発生した具体的な原因を表示しますが、業務の発展や体験の最適化に伴い、このテキストは頻繁に変更または更新される可能性があります。ユーザーはこの戻り値に依存すべきではありません。RequestIdはAPIリクエストの唯一の識別子として使用されます。APIに異常が発生した場合は、該当 ID を添えて連絡してください。エラーコード | エラー説明 |
AuthFailure.InvalidSecretId | キーが無効です(TencentCloud APIキータイプではありません)。 |
AuthFailure.MFAFailure | MFAエラーです。 |
AuthFailure.SecretIdNotFound | シークレットキーが存在しません。 |
AuthFailure.SignatureExpire | シグネチャの期限切れです。 |
AuthFailure.SignatureFailure | シグネチャエラーです。 |
AuthFailure.TokenFailure | tokenエラーです。 |
AuthFailure.UnauthorizedOperation | リクエストはCAM認可が取得されていません。 |
DryRunOperation | DryRunオペレーションは、リクエストが成功することを意味しますが、余分にDryRunパラメータが渡されただけです。 |
FailedOperation | 操作に失敗しました。 |
InternalError | 内部エラーです。 |
InvalidAction | APIが存在しません。 |
InvalidParameter | パラメータエラーです。 |
InvalidParameterValue | パラメータ値エラーです。 |
LimitExceeded | クォータ制限を超過しました。 |
MissingParameter | パラメータ不足エラーです。 |
NoSuchVersion | APIバージョンが存在しません。 |
RequestLimitExceeded | リクエスト回数がレート制限を超過しました。 |
ResourceInUse | リソースが使用中です。 |
ResourceInsufficient | リソース不足です。 |
ResourceNotFound | リソースが存在しません。 |
ResourceUnavailable | リソースは利用不可です。 |
UnauthorizedOperation | 操作は認可されていません。 |
UnknownParameter | 未知パラメータエラーです。 |
UnsupportedOperation | 操作はサポートされていません。 |
UnsupportedProtocol | HTTPSリクエスト方法が正しくありません。GETとPOSTリクエストのみサポートしています。 |
UnsupportedRegion | APIは指定されたリージョンをサポートしていません。 |
フィードバック