この例では、OSS SDK の組み込み署名に依存せずに、Python 2.7 で Authorization ヘッダーを手動で構築し、PutObject API を使用してオブジェクトを OSS にアップロードする方法を示します。
本番環境では、リクエスト署名を自動的にハンドルする OSS SDK を使用してください。この例は、たとえば OSS をカスタム HTTP スタックに統合する場合や、認証フローをデバッグする場合など、SDK を使用できないときにのみ使用してください。
前提条件
開始する前に、以下があることを確認してください。
AccessKey ID と AccessKey Secret を持つ Alibaba Cloud アカウント
oss-cn-hangzhouリージョンにある OSS バケット (または、ご利用のバケットのリージョンに合わせてエンドポイントを更新してください)アップロードするローカルファイル
標準ライブラリ (
hmac、base64、urllib2) が利用可能な Python 2.7
仕組み
署名付き PutObject リクエストには、次の 3 つのヘッダーが必要です。
| ヘッダー | 説明 |
|---|---|
Authorization | リクエストを認証します。形式: OSS <AccessKeyID>:<Base64(HMAC-SHA1(StringToSign))> |
Content-Type | アップロードされるオブジェクトの MIME タイプ (例: image/png) |
Date | 署名を計算する際に使用された時刻と一致する、GMT 形式の現在の UTC 時刻 |
Authorization ヘッダー形式
Authorization ヘッダーは次の構造を持ちます。
OSS <AccessKeyID>:<Signature>| コンポーネント | 説明 |
|---|---|
OSS | Alibaba Cloud OSS 署名スキームを識別する固定プレフィックス |
<AccessKeyID> | ご利用の AccessKey ID |
: | AccessKey ID と署名の間の区切り文字 |
<Signature> | 署名文字列の Base64 エンコードされた HMAC-SHA1 ハッシュ |
署名文字列形式
署名文字列は次のように構築されます。
PUT\n
\n
<Content-Type>\n
<Date>\n
/<bucket>/<object>ここで、各 \n はリテラル改行文字です。
署名付きリクエストでのオブジェクトのアップロード
次の Python 2.7 コードは、署名を構築し、PutObject API を使用してオブジェクトをアップロードします。
実行する前に、プレースホルダー値を置き換えてください。
| プレースホルダー | 説明 | 例 |
|---|---|---|
Your accesskey | ご利用の AccessKey ID | LTAI5tXxxx |
Your AccesskeySecret | ご利用の AccessKey Secret | xXxXxXx |
Your bucket name | ご利用の OSS バケット名 | examplebucket |
/Users/wanghe/Documents/20190717101549.png | アップロードするファイルのローカルパス | /path/to/your/file.png |
# -*- coding: utf-8 -*-
import base64
import hmac
import sha
import urllib2
from datetime import datetime
accesskey='Your accesskey';
accesskeysecret='Your AccesskeySecret
endpoint='oss-cn-hangzhou.aliyuncs.com'
bucket='Your bucket name'
# アップロードするオブジェクトのパス。
object='mytest/test.png'
GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
time = datetime.utcnow().strftime(GMT_FORMAT)
print(time)
signature = hmac.new(accesskeysecret,
"PUT\n\nimage/png\n"+time+"\n"+"/"+bucket+"/"+object,sha)
Signature = base64.b64encode(signature.digest())
print("Signature: %s" % Signature)
opener = urllib2.build_opener(urllib2.HTTPHandler)
with open("/Users/wanghe/Documents/20190717101549.png") as f:
data=f.read()
request = urllib2.Request("http://"+bucket+"."+endpoint+"/"+object, data=data)
request.add_header("Authorization", "OSS "+accesskey+":"+Signature)
request.add_header("Content-Type", "image/png")
request.add_header("Date", time)
request.get_method = lambda:"PUT"
url = opener.open(request)トラブルシューティング
署名が正しくない場合、OSS は 403 SignatureDoesNotMatch エラーを返します。一般的な原因は次のとおりです。
署名の計算に使用された
Date値が、リクエストで送信されたDateヘッダーと一致しない署名文字列が各フィールド間にリテラル改行文字を使用していない
署名文字列内の
Content-Type値が、リクエスト内のContent-Typeヘッダーと一致しない
次のステップ
ヘッダーへの署名の追加 — OSS 署名アルゴリズムの完全なリファレンス