【JavaScript】Google Maps APIのAPIキーを公開せずにGitHubにpushする方法

プログラミング

背景

Googleからは様々なAPI(Application Programming Interface)が公開されている。

その中でも、WEBサイトに追加でき、更にカスタマイズも可能なGoogle Maps JavaScript APIを用いたアプリを開発中。

APIを用いたアプリ開発における注意点として、APIキーがGitHub等で公開されてしまうとセキュリティ上、よろしくないということで、APIキーを公開せずにGitHubにpushする方法を検討した。

下記は、Googleの公式サイトで掲載されている、Google Maps JavaScript APIを用いた基本的なサンプルコード。

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          zoom: 8
        });
      }
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&amp;callback=initMap"
    async defer></script>
  </body>
</html>

32行目に、key=YOUR_API_KEYと書かれており、YOUR_API_KEYに自分のAPIキーを入力する必要があるのだが、このままだとGitHubにプッシュしたらAPIキーが公開されてしまう。

Google公式ドキュメントでも下記のように記載されている。

アプリケーションで API キーを利用するときは、キーの安全確保に努めてください。認証情報が公開されると、アカウントが侵害され、アカウントに対して予想外の料金が課される可能性があります。

Google Cloud 公式ドキュメント

対策方法

まずは、APIキー入力用のファイル(例えば、googlemaps.js)を用意し、下記のように記載。

const gmapapi = {
  API_KEY : '自分のAPIキー'
};

次に、JavaScriptやjQueryなどを書いていくファイル(例えば、main.js)で上記API_KEYを呼び出す。

const myApiKey = gmapapi.API_KEY;
const url = `https://maps.googleapis.com/maps/api/js?key=${myApiKey}&amp;callback=initMap`;
const script = document.createElement('script');
script.setAttribute('src', url);
script.setAttribute('async', true);
script.setAttribute('defer', true);
document.body.appendChild(script);
  1. APIキーを読み出す
  2. テンプレート文字列を用いて、urlにAPIキーを代入
  3. script要素をdocument.createElement('script')で作成
  4. setAttributeメソッドで、src属性にurlをセットし、async属性とdefer属性をtrueにセット
  5. 最後に、生成したscript要素をappendChildメソッドでHTMLのbody要素の最後に追加

なお、async属性は、ページの読み込み中に、そのスクリプトが利用可能になった時点で実行され、

defer属性は、ページの読み込みが完了した時点で、そのスクリプトが実行される。

両方が指定してあると、まずasync属性の方法で実行されるが、その方法に対応していないブラウザではdefer属性の方法で実行される(参考)。

HTMLでは、main.jsの前にgooglemaps.jsを先に記載。

  <script>
    let map;
    function initMap() {
      map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: -34.397, lng: 150.644},
        zoom: 8
      });
    }
  </script>

  <script src='googlemaps.js'></script>
  <script src="main.js"></script>

ChromeのデベロッパーツールでHTMLを確認すると、下記のscript要素が生成されている。

<script src="https://maps.googleapis.com/maps/api/js?key=(自分のAPIキー)&amp;callback=initMap" async="true" defer="true"></script>

最後に、肝心のAPIキーが記載されたファイル(googlemaps.js)を.gitignoreに追記することで、GitHubにpushしてもAPIキーが記載されたgooglemaps.js(APIキー)は公開されない。

これで、APIキーを公開することなく、GitHubにプッシュが可能となる。