1

GAEではhmac、AWSAPIリクエストの署名を生成するために使用しています。私のコードはもともとこれでした:

import urllib
import urllib2
import time
import hmac
import base64
from hashlib import sha256 as sha256

class AmazonProductAdvertisingAPI:

    secret_access_key = '...'
    my_hmac = hmac.new(secret_access_key, digestmod=sha256)

    def get_signed_url(self, params):

        ....

        # Sign it
        self.my_hmac.update('GET' + "\n" + server + "\n" + path + "\n" + paramstring)
        urlstring = urlstring + "&Signature=" + \
            urllib.quote(base64.encodestring(self.my_hmac.digest()).strip())

        return urlstring

これにより、APIリクエスト(で指定されたURLを使用get_signed_url)は、リクエストがインスタンスの「コールドスタート」である場合にのみ、たとえばコードをデプロイして初めて実行した後などにわかりました。

ただし、その後のリクエストは失敗し、AWSは署名が無効であると主張しました。これは、メソッド内に移動my_hmacすることで解決されたため、クラス内のインスタンス変数ではなく、メソッド内の変数になりました。

...
def get_signed_url(self, params):
    my_hmac = hmac.new(self.secret_access_key, digestmod=sha256)
    ...

私は1つの質問があります:なぜですか?

4

1 に答える 1

4

あなたのmy_hmac変数はクラス変数でした。クラスのすべてのインスタンスで共有されるもの。

これは、呼び出しを.get_signed_url()呼び出すself.my_hmac.update()たびに、インスタンス全体で、アプリケーションにグローバルにデータをダイジェストに追加することを意味します。

"GET ..."すべての文字列に対して累積的にではなく、1つの文字列(文字列)に対してのみダイジェストを計算する必要があるため、計算する新しいダイジェストごとに新しいオブジェクトを作成する必要があります。hmac

.update()`メソッドのドキュメントに注意してください。

文字列argでハッシュオブジェクトを更新します。繰り返される呼び出しは、すべての引数を連結した単一の呼び出しと同等です。m.update(a); m.update(b)はと同等m.update(a+b)です。

于 2013-02-10T00:19:17.430 に答える