如何使用SHA-1 HMAC为ruby中的谷歌地图生成签名

时间:2014-05-21 07:33:33

标签: ruby hmacsha1

我正在尝试使用ruby中的SHA-1 HMAC为谷歌地图调用生成签名。我从互联网上得到了一个python的代码,我试图将其复制到ruby中。以下是phython的代码

import urllib.parse
import base64
import hashlib
import hmac 
GOOGLEAPIS_URL = 'http://maps.googleapis.com'
STREETVIEW_ENDPOINT = '/maps/api/streetview'
encodedParams = urllib.parse.urlencode({'size':'50x50','location':'42.35878993272469,-71.05793081223965','sensor':'false','client':'gme-securealert'});
privateKey = 'Encoded_Key' # e.g XEL-B9Zs3lRLajIXkD-bqTYix20=
decodedKey = base64.urlsafe_b64decode(privateKey)
urlToSign = STREETVIEW_ENDPOINT + '?' + encodedParams
print(urlToSign)
signature = hmac.new(decodedKey, urlToSign.encode('utf-8') , hashlib.sha1)
encodedSignature = base64.urlsafe_b64encode(signature.digest())
print(encodedSignature

生成 OI2DXDLq7Qd790Lokaxgqtis_pE = 签名。

以下是我试图与。#/ p>实现相同签名的Ruby代码

GOOGLE_APIS_URL= "http://maps.googleapis.com"      
key = Encoded_Key # e.g XEL-B9Zs3lRLajIXkD-bqTYix20=
data ='/maps/api/streetview?size=50x50&sensor=false&client=gme-securealert&location=42.35878993272469,-71.05793081223965'

data_array = data.split("?")
STREET_VIEW_ENDPOINT = data_array[0]
query_string = data_array[1]

encoded_query_string =  URI.escape(query_string) # to encode parameters only
decoded_key = Base64.decode64(key) # to decode the key

data = STREET_VIEW_ENDPOINT << '?' << encoded_query_string
#p "DATA #{data}"
#data = Base64.decode64(data)
#puts "data #{data}"
digest = OpenSSL::Digest.new('sha1')
p OpenSSL::HMAC.digest(digest, decoded_key, data)
hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, decoded_key, data))
p hmac

但这对我来说似乎不起作用。 请指导。

1 个答案:

答案 0 :(得分:1)

您可以为请求参数创建哈希,并使用URI.encode_www_form来编码参数。使用Base64.urlsafe_decode64和Base64.urlsafe_encode64代替Base64.decode64和Base64.encode64。就我而言,我使用了反向地理编码api。您需要修改参数和REVERSE_GEOCODING_ENDPOINT_JSON。希望这会帮助你。如果您有任何疑问,请与我们联系。

GOOGLE_MAPS_API_CLIENT_ID = 'gme-xyz'
GOOGLE_MAPS_API_CRYPTO_KEY = 'private_key'
GOOGLEAPIS_HTTP_URL = 'http://maps.googleapis.com'
REVERSE_GEOCODING_ENDPOINT_JSON = '/maps/api/geocode/json'

str_latlng = lat.to_s + ',' + lon.to_s
encoded_params = URI.encode_www_form({'latlng' => str_latlng,
                                      'client' => GOOGLE_MAPS_API_CLIENT_ID})
decoded_key = Base64.urlsafe_decode64(GOOGLE_MAPS_API_CRYPTO_KEY)
url_to_sign = REVERSE_GEOCODING_ENDPOINT_JSON + '?' + encoded_params
digest = OpenSSL::Digest.new('sha1')
signature = OpenSSL::HMAC.digest(digest, decoded_key, url_to_sign)
encoded_signature = Base64.urlsafe_encode64(signature)
signed_url = GOOGLEAPIS_HTTP_URL + REVERSE_GEOCODING_ENDPOINT_JSON + '?' + encoded_params + '&signature='+encoded_signature