認証と承認

このページは、以前の Maps APIs for Work または Maps API for Business ライセンスのユーザーのみを対象にしています。このページの内容は、2016 年 1 月から利用可能になった新しい Google Maps APIs Premium Plan のユーザーには適用されません。

クライアント ID と署名

Google Maps APIs for Work ユーザーの場合、イメージ API(Static Maps API および Street View Image API)にクライアント ID と一意の署名を渡して署名を行います。

クライアント ID と署名

Google Maps APIs for Work ライセンスでイメージ API を使用する場合、標準のパラメータに加えて、次の 2 つの認証パラメータが必要です。

  • クライアント ID。Google Maps APIs for Work の特別な機能にアクセスするには、API ライブラリまたはサービスへのアクセス時に必ずクライアント ID を指定する必要があります。Google Maps APIs for Work の登録をすると、Google Cloud Support Portal からこのクライアント ID が送られてきます。すべてのクライアント ID は接頭辞 gme- で始まります。クライアント ID は client パラメータの値として渡します。

  • 一意の署名。秘密暗号化キーを使用して生成します。この署名は signature パラメータの値として渡します。署名の生成については、以下のデジタル署名のセクションで詳しく説明しています。

Static Maps API:

    <img src="https://maps.googleapis.com/maps/api/staticmap
      ?center=-15.800513,-47.91378
      &zoom=11
      &size=300x300
      &client=YOUR_CLIENT_ID
      &signature=SIGNATURE">

Street View Image API:

    <img src="https://maps.googleapis.com/maps/api/streetview
      ?location=40.720032,-73.988354
      &size=400x400
      &fov=90&heading=235&pitch=10
      &client=YOUR_CLIENT_ID
      &signature=SIGNATURE">

リクエストに key パラメータを含めないでください

Google Maps APIs for Work ユーザーのデジタル署名

Google Maps APIs for Work ユーザーがイメージ API にリクエストを送信する場合は、ウェルカム メールで提供された秘密暗号化キーを使って生成したデジタル signature が必要です。

署名プロセスでは、暗号化アルゴリズムによって URL とキーが統合されます。生成された一意の署名により、Google のサーバーでは、クライアント ID を使用してリクエストを生成しているサイトにその処理が承認されていることを確認できます。また、署名は URL ごとに一意であるため、新しい署名の生成を求めることなく、クライアント ID を使用したリクエストを変更することはできません。

秘密暗号化キー

秘密暗号化 URL 署名キーはクライアント ID で発行され、ユーザーと Google 間の「シークレット共有キー」になります。この署名キーはユーザー個人のものであり、クライアント ID に固有のキーです。そのため、署名キーのセキュリティを確保する必要があります。このキーをリクエストで渡したり、ウェブサイトに保存したり、公開フォーラムに投稿したりしないでください。この署名キーを取得した誰かが、あなたの ID を使用してリクエストを偽装する可能性があります。

注: この秘密暗号化署名キーは、Google API Console で発行された API キーと同じではありません

秘密暗号化キーを紛失した場合は、Google Cloud Support Portal にログインし、[Maps: Manage Client ID] をクリックしてキーを再取得してください。

デジタル署名を生成する

無効な署名を使用してイメージ API へのアクセスを試みると、HTTP 403 (Forbidden) エラーが発生します。アプリケーションを変更して URL 署名を使用するときは、署名をテストして、有効なリクエストが開始されるようにする必要があります。まず元の URL が有効かどうかに加えて、正しい署名が生成されるかどうかをテストする必要があります。

次の手順でリクエストのデジタル署名を作成します。

  1. client パラメータを必ず含め、署名なしでリクエスト URL を作成します。非標準文字は URL エンコードする必要があることに注意してください。

    Static Maps API: https://maps.googleapis.com/maps/api/staticmap?center=40.714%2c%20-73.998&zoom=12&size=400x400&client=clientID

    Street View Image API: https://maps.googleapis.com/maps/api/streetview?location=41.403609,2.174448&size=456x456&client=clientID

    注: すべての Google サービスに UTF-8 文字エンコード(暗黙的に ASCII を含む)が必要です。アプリケーションが他の文字セットを使用して動作している場合は、UTF-8 を使用して URL を作成し、その文字セットが正しく URL にエンコードされるようにしてください。

  2. パスとクエリのみを残して、リクエストのドメイン部分を取り除きます。

    Static Maps API: /maps/api/staticmap?center=40.714%2c%20-73.998&zoom=12&size=400x400&client=clientID

    Street View Image API: /maps/api/streetview?location=41.403609,2.174448&size=456x456&client=clientID

  3. URL 用 Modified Base64 でエンコードされた秘密キーを取得し、HMAC-SHA1 アルゴリズムを使用して上記の URL に署名します。場合によっては、このキーを元のバイナリ形式にデコードする必要があります。なお、ほとんどの暗号化ライブラリで生成される署名はバイナリ形式です。

    注: URL 用 Modified Base64 では、標準の Base64 の + 文字と / 文字がそれぞれ -_ に置き換えられるため、これらの Base64 署名は URL にエンコードする必要はなくなりました。

  4. 生成されたバイナリ署名を、URL 用 Modified Base64 でエンコードして、この署名を URL 内で渡すことができるように変換します。

  5. この署名を signature パラメータの URL に付加します。

    Static Maps API:https://maps.googleapis.com/maps/api/staticmap?center=40.714%2c%20-73.998&zoom=12&size=400x400&client=clientID&signature=base64signature

    Street View Image API:https://maps.googleapis.com/maps/api/streetview?location=41.403609,2.174448&size=456x456&client=clientID&signature=base64signature

サーバー側のコードを使用して URL 署名を実装する方法を示したサンプルについては、URL 署名のサンプル コードをご覧ください。

URL 署名のサンプル コード

次のセクションでは、サーバー側のコードを使用して URL 署名を実装する方法について説明します。暗号化キーがユーザーに表示されないように、URL への署名は常にサーバー側で行う必要があります。

Python

次の例では、標準の Python ライブラリを使用して URL に署名しています。(コードのダウンロード

#!/usr/bin/python
# -*- coding: utf-8 -*-
""" Signs a URL using a URL signing secret """

import hashlib
import hmac
import base64
import urlparse

def sign_url(input_url=None, secret=None):
  """ Sign a request URL with a URL signing secret.

      Usage:
      from urlsigner import sign_url

      signed_url = sign_url(input_url=my_url, secret=SECRET)

      Args:
      input_url - The URL to sign
      secret    - Your URL signing secret

      Returns:
      The signed request URL
  """

  if not input_url or not secret:
    raise Exception("Both input_url and secret are required")

  url = urlparse.urlparse(input_url)

  # We only need to sign the path+query part of the string
  url_to_sign = url.path + "?" + url.query

  # Decode the private key into its binary format
  # We need to decode the URL-encoded private key
  decoded_key = base64.urlsafe_b64decode(secret)

  # Create a signature using the private key and the URL-encoded
  # string using HMAC SHA1. This signature will be binary.
  signature = hmac.new(decoded_key, url_to_sign, hashlib.sha1)

  # Encode the binary signature into base64 for use within a URL
  encoded_signature = base64.urlsafe_b64encode(signature.digest())

  original_url = url.scheme + "://" + url.netloc + url.path + "?" + url.query

  # Return signed URL
  return original_url + "&signature=" + encoded_signature

if __name__ == "__main__":
  input_url = raw_input("URL to Sign: ")
  secret = raw_input("URL signing secret: ")
  print "Signed URL: " + sign_url(input_url, secret)

Java

次の例では、JDK 1.8 から利用できる java.util.Base64 クラスを使用しています。それより古いバージョンでは、Apache Commons またはそれに類するものを使用する必要があります。(コードのダウンロード

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;  // JDK 1.8 only - older versions may need to use Apache Commons or similar.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class UrlSigner {

  // Note: Generally, you should store your private key someplace safe
  // and read them into your code

  private static String keyString = "YOUR_PRIVATE_KEY";
  
  // The URL shown in these examples is a static URL which should already
  // be URL-encoded. In practice, you will likely have code
  // which assembles your URL from user or web service input
  // and plugs those values into its parameters.
  private static String urlString = "YOUR_URL_TO_SIGN";

  // This variable stores the binary key, which is computed from the string (Base64) key
  private static byte[] key;
  
  public static void main(String[] args) throws IOException,
    InvalidKeyException, NoSuchAlgorithmException, URISyntaxException {
    
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    
    String inputUrl, inputKey = null;

    // For testing purposes, allow user input for the URL.
    // If no input is entered, use the static URL defined above.    
    System.out.println("Enter the URL (must be URL-encoded) to sign: ");
    inputUrl = input.readLine();
    if (inputUrl.equals("")) {
      inputUrl = urlString;
    }
    
    // Convert the string to a URL so we can parse it
    URL url = new URL(inputUrl);
 
    // For testing purposes, allow user input for the private key.
    // If no input is entered, use the static key defined above.   
    System.out.println("Enter the Private key to sign the URL: ");
    inputKey = input.readLine();
    if (inputKey.equals("")) {
      inputKey = keyString;
    }
    
    UrlSigner signer = new UrlSigner(inputKey);
    String request = signer.signRequest(url.getPath(),url.getQuery());
    
    System.out.println("Signed URL :" + url.getProtocol() + "://" + url.getHost() + request);
  }
  
  public UrlSigner(String keyString) throws IOException {
    // Convert the key from 'web safe' base 64 to binary
    keyString = keyString.replace('-', '+');
    keyString = keyString.replace('_', '/');
    System.out.println("Key: " + keyString);
    // Base64 is JDK 1.8 only - older versions may need to use Apache Commons or similar.
    this.key = Base64.getDecoder().decode(keyString);
  }

  public String signRequest(String path, String query) throws NoSuchAlgorithmException,
    InvalidKeyException, UnsupportedEncodingException, URISyntaxException {
    
    // Retrieve the proper URL components to sign
    String resource = path + '?' + query;
    
    // Get an HMAC-SHA1 signing key from the raw key bytes
    SecretKeySpec sha1Key = new SecretKeySpec(key, "HmacSHA1");

    // Get an HMAC-SHA1 Mac instance and initialize it with the HMAC-SHA1 key
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(sha1Key);

    // compute the binary signature for the request
    byte[] sigBytes = mac.doFinal(resource.getBytes());

    // base 64 encode the binary signature
    // Base64 is JDK 1.8 only - older versions may need to use Apache Commons or similar.
    String signature = Base64.getEncoder().encodeToString(sigBytes);
    
    // convert the signature to 'web safe' base 64
    signature = signature.replace('+', '-');
    signature = signature.replace('/', '_');
    
    return resource + "&signature=" + signature;
  }
}

C#

次の例では、デフォルトの System.Security.Cryptography ライブラリを使用して URL リクエストに署名しています。URL セーフ バージョンを実装するには、デフォルトの Base64 エンコーディングを変換する必要があります。(コードのダウンロード

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace SignUrl {

  public struct GoogleSignedUrl {

    public static string Sign(string url, string keyString) {
      ASCIIEncoding encoding = new ASCIIEncoding();

      // converting key to bytes will throw an exception, need to replace '-' and '_' characters first.
      string usablePrivateKey = keyString.Replace("-", "+").Replace("_", "/");
      byte[] privateKeyBytes = Convert.FromBase64String(usablePrivateKey);

      Uri uri = new Uri(url);
      byte[] encodedPathAndQueryBytes = encoding.GetBytes(uri.LocalPath + uri.Query);

      // compute the hash
      HMACSHA1 algorithm = new HMACSHA1(privateKeyBytes);
      byte[] hash = algorithm.ComputeHash(encodedPathAndQueryBytes);

      // convert the bytes to string and make url-safe by replacing '+' and '/' characters
      string signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_");
            
      // Add the signature to the existing URI.
      return uri.Scheme+"://"+uri.Host+uri.LocalPath + uri.Query +"&signature=" + signature;
    }
  }

  class Program {

    static void Main() {
    
      // Note: Generally, you should store your private key someplace safe
      // and read them into your code

      const string keyString = "YOUR_PRIVATE_KEY";
  
      // The URL shown in these examples is a static URL which should already
      // be URL-encoded. In practice, you will likely have code
      // which assembles your URL from user or web service input
      // and plugs those values into its parameters.
      const  string urlString = "YOUR_URL_TO_SIGN";
      
      string inputUrl = null;
      string inputKey = null;
    
      Console.WriteLine("Enter the URL (must be URL-encoded) to sign: ");
      inputUrl = Console.ReadLine();
      if (inputUrl.Length == 0) {
        inputUrl = urlString;
      }     
    
      Console.WriteLine("Enter the Private key to sign the URL: ");
      inputKey = Console.ReadLine();
      if (inputKey.Length == 0) {
        inputKey = keyString;
      }
      
      Console.WriteLine(GoogleSignedUrl.Sign(inputUrl,inputKey));
    }
  }
}

認証の問題のトラブルシューティング

リクエストが不正であるか、または無効な署名を提供している場合は、イメージ API から HTTP 403 (Forbidden) エラーが返されます。

個々の URL をトラブルシューティングするために、URL Signing Debugger を使用できます。これを使用すると、URL やアプリケーションによって生成された署名をすばやく検証できます。

または、Google Maps APIs for Work ユーザーは、Google Cloud Support Portal にログインし、[Resources] > [Google Maps APIs for Work online tools] > [URL Signing Debugger for Web Service and Image APIs] を選択して、個々の URL のトラブルシューティングを行うことができます。