Webdevelopment – Ruby on Rails – PHP – CSS – AJAX
10 Sep
Änderungen an der Amazon Schnittstelle
Anfang August hat Amazon seine API entscheidend umgestellt – alle Zugriffe müssen mit dem API-Secret auf relativ komplizierte Art und Weise signiert werden. Ich nutzte bisher das Plugin “amazon-aws”, welches diese Signierung aber leider nicht unterstützt.
Da der Amazonproduktdatenimport in meinen Projekten also seit August nicht mehr funktioniert hatte entschloss ich mich dazu das Plugin entsprechend zu erweitern und auf github zur Verfügung zu stellen.
Änderungen am Plugin:
Die erste Änderung betrifft die Datei /lib/amazon/aws.rb dieser habe ich im Kopfbereich folgendes Modul hinzugefügt welches für die spätere Verschlüsselung der Signatur zuständig ist:
module HMAC IPAD = "\x36" * 64 OPAD = "\x5c" * 64 module_function def sha256( key, message ) ikey = IPAD.dup okey = OPAD.dup key.size.times do |i| ikey[i] = key[i] ^ IPAD[i] okey[i] = key[i] ^ OPAD[i] end value = Digest::SHA256.digest( ikey + message ) value = Digest::SHA256.digest( okey + value ) end end
Als nächstes wurde dem Modul AWS eine Metode hinzugefügt, welche die eigentliche Signatur erstellt:
def self.signature_for_request(request, query, method = 'GET' ) endpoint = ENDPOINT[request.locale] host = endpoint.host uri = endpoint.path query.gsub!('?', '') raw_signature = "#{method}\n#{host}\n#{uri}\n#{query}" hash = HMAC::sha256(request.secret_id, raw_signature) signature = Base64.encode64(hash).chomp Amazon.rawurlencode signature end
Zuletzt habe ich in der AWS::get_page methode die Signatur an die URL gehängt:
url = ENDPOINT[request.locale].path + query + "&Signature=" + AWS.signature_for_request(request, query)
In der Datei lib/amazon/aws/search.rb habe ich in Search::Request den intializer etwas erweitert, schließlich muss ja der SECRET-KEY mittlerweile auch übergeben werden:
def initialize(key_id=nil, secret_id=nil, associate=nil, locale=nil, cache=nil, cache_dir=nil, user_agent=USER_AGENT) @config ||= Amazon::Config.new def_locale = locale locale = 'us' unless locale locale.downcase! key_id ||= @config['key_id'] secret_id ||= @config['secret_id'] cache = @config['cache'] if cache.nil? cache_dir ||= @config['cache_dir'] # Take locale from config file if no locale was passed to method. # if @config.key?( 'locale' ) && ! def_locale locale = @config['locale'] end validate_locale( locale ) if key_id.nil? raise AccessKeyIdError, 'key_id may not be nil' end if secret_id.nil? raise AccessKeyIdError, 'secrret_id may not be nil' end @key_id = key_id @secret_id = secret_id @tag = associate || @config['associate'] || DEF_ASSOC[locale] @user_agent = user_agent @cache = unless cache == 'false' || cache == false Amazon::AWS::Cache.new( cache_dir ) else nil end self.locale = locale end
Bei allen Search::Requests übergeben wir jetzt also auch den SECRETKEY und schon läuft das Ganze wieder – so lange bis amazon wieder irgendwas ändert
Leave a reply