mirror of
https://github.com/imjasonh/staticmaps
synced 2026-07-08 19:05:09 +00:00
Correctly generate the signature based on a private key
This commit is contained in:
parent
e2af009927
commit
1704d37fbe
2 changed files with 58 additions and 10 deletions
55
maps.go
55
maps.go
|
|
@ -1,15 +1,18 @@
|
|||
package maps
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const baseURL = "https://maps.googleapis.com/maps/api/"
|
||||
|
||||
const (
|
||||
baseURL = "https://maps.googleapis.com/maps/api/"
|
||||
|
||||
// StatusOK indicates the response contains a valid result.
|
||||
StatusOK = "OK"
|
||||
// StatusNotFound indicates at least one of the locations specified could not be geocoded.
|
||||
|
|
@ -32,8 +35,21 @@ const (
|
|||
|
||||
// Client provides methods to make requests of various Maps APIs.
|
||||
type Client struct {
|
||||
Transport http.RoundTripper
|
||||
Key, ClientID, Signature string
|
||||
// The underlying http.RoundTripper to use. If this is not specified, http.DefaultTransport will be used.
|
||||
Transport http.RoundTripper
|
||||
|
||||
// Key is the API key to use to authorize requests.
|
||||
Key string
|
||||
|
||||
// ClientID is the Google Maps API for Work client ID to use.
|
||||
//
|
||||
// See https://developers.google.com/maps/documentation/business/webservices/auth
|
||||
ClientID string
|
||||
|
||||
// PrivateKey is the base64-encoded private key to use for Google Maps API for Work requests.
|
||||
//
|
||||
// See https://developers.google.com/maps/documentation/business/webservices/auth
|
||||
PrivateKey string
|
||||
}
|
||||
|
||||
// NewClient returns a Client using the specified API key.
|
||||
|
|
@ -44,8 +60,8 @@ func NewClient(key string) Client {
|
|||
// NewWorkClient returns a Client using the specified Google Maps API for Work client ID and signature.
|
||||
//
|
||||
// See https://developers.google.com/maps/documentation/business/
|
||||
func NewWorkClient(clientID, signature string) Client {
|
||||
return Client{ClientID: clientID, Signature: signature, Transport: http.DefaultTransport}
|
||||
func NewWorkClient(clientID, privateKey string) Client {
|
||||
return Client{ClientID: clientID, PrivateKey: privateKey, Transport: http.DefaultTransport}
|
||||
}
|
||||
|
||||
func (c Client) do(url string) (*http.Response, error) {
|
||||
|
|
@ -61,15 +77,34 @@ func (c Client) do(url string) (*http.Response, error) {
|
|||
q.Set("key", c.Key)
|
||||
}
|
||||
if c.ClientID != "" {
|
||||
q.Set("clientId", c.ClientID)
|
||||
q.Set("client", c.ClientID)
|
||||
}
|
||||
if c.Signature != "" {
|
||||
q.Set("signature", c.Signature)
|
||||
enc := q.Encode()
|
||||
if c.PrivateKey != "" {
|
||||
sig, err := c.genSig(req.URL.Path, enc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
enc += "&signature=" + sig
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
req.URL.RawQuery = enc
|
||||
return cl.Get(url)
|
||||
}
|
||||
|
||||
// See https://developers.google.com/maps/documentation/business/webservices/auth
|
||||
func (c Client) genSig(path, query string) (string, error) {
|
||||
toSign := path + "?" + query
|
||||
decodedKey, err := base64.URLEncoding.DecodeString(c.PrivateKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
d := hmac.New(sha1.New, decodedKey)
|
||||
if _, err := d.Write([]byte(toSign)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(d.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func (c Client) doDecode(url string, r interface{}) error {
|
||||
resp, err := c.do(url)
|
||||
if err != nil {
|
||||
|
|
|
|||
13
maps_test.go
13
maps_test.go
|
|
@ -176,3 +176,16 @@ func TestDistanceMatrix(t *testing.T) {
|
|||
t.Logf("%v", r)
|
||||
|
||||
}
|
||||
|
||||
// Based on https://developers.google.com/maps/documentation/business/webservices/auth#signature_examples
|
||||
func TestSignature(t *testing.T) {
|
||||
c := NewWorkClient("", "vNIXE0xscrmjlyV-12Nj_BvUPaw=")
|
||||
sig, err := c.genSig("/maps/api/geocode/json", "address=New+York&client=clientID")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
exp := "chaRF2hTJKOScPr-RQCEhZbSzIE="
|
||||
if sig != exp {
|
||||
t.Errorf("wrong signature, got %q, want %q", sig, exp)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue