Google Cloud Storage(GCS)に直接ファイルをアップロードするための署名付きURLを作成しようとしています。私はを使ってこの作業を行い、ポリシーを利用してthis Github exampleを使用しました。ベストプラクティスごとに、私はPUTを使用するためにリファクタリングとSignatureDoesNotMatch
エラーになっている:私の署名文字列を構築GCS PUTリクエストのGAEで署名されたURL
- :
creating a signed URL with a program上のドキュメント毎の<?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>PUT 123456789 /mybucket/mycat.jpg</StringToSign></Error>
とGCP example Python codeを、私はこのプロセスをしていますそれは
が結果をコード
- URL(Pythonの例はしかしこれを実行しないエンコードすること
- BASE64に署名
- ...
これはGoogle App Engine(GAE)アプリで実行されているため、サービスアカウントのユーザー用にJSONキーファイルを取得する必要はなく、App Identity Servicesを使用して署名する必要があります。ここに私のコードは、フラスコのプロジェクト内です:
google_access_id = app_identity.get_service_account_name()
expires = arrow.utcnow().replace(minutes=+10).replace(microseconds=0).timestamp
resource = '/mybucket/mycat.jpg'
args = self.get_parser.parse_args()
signature_string = 'PUT\n'
# take MD5 of file being uploaded and its content type, if provided
content_md5 = args.get('md5') or ''
content_type = args.get('contenttype') or ''
signature_string = ('PUT\n'
'{md5}\n'
'{content_type}\n'
'{expires}\n'
'{resource}\n').format(
md5=content_md5,
content_type=content_type,
expires=expires,
resource=resource)
log.debug('signature string:\n{}'.format(signature_string))
_, signature_bytes = app_identity.sign_blob(signature_string)
signature = base64.b64encode(signature_bytes)
# URL encode signature
signature = urllib.quote(signature)
media_url = 'https://storage.googleapis.com{}'.format(resource)
return dict(GoogleAccessId=google_access_id,
Expires=expires,
Signature=signature,
bucket='mybucket',
media_url='{}?GoogleAccessId={}&Expires={}&Signature={}'.format(media_url, google_access_id, expires, signature))
log.debug
文は完全に上記のGCS XMLエラー応答に署名と一致する署名ファイルを印刷します。一致すれば、なぜアップロードできないのですか?
gsutil
を使用すると、同じGAEサービスアカウントを使用して署名付きURLを作成することができ、Postmanでもうまく動作します。私はgsutil
の署名をURLエンコードしていますが、自分で署名したURLを作成しても、どちらの方法でも問題にはならないと思われます。GCSはPUTリクエストを取得し、署名が一致しないと訴えますログに記録されたデバッグメッセージ。私はまた元の署名文字列の後ろに\ nを付けて試しました。
EDIT:それはそれに署名した後、私はBase64 encodes the Policy before it sings、と再びを踏襲POST
例。私はこの手法をPUTシグネチャの作成で試してみましたが、違いはありませんでした。
'md5'または 'contenttype' argsを指定していますか?実際のリクエストでは、リクエスト自体にリクエストが指定されていないようです。あなたのデバッグ文で生成される値は ''要素の値と正確に一致しますか? –
私の要求にmd5やコンテンツタイプの詳細が含まれていないし、署名付き文字列にも指定されていない。これまでのところ内容は全く同じであることが分かります。私が署名した文字列は、返されたXML値と 'SignToString' – hamx0r