28
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Google Maps API キーをHTMLから隠す方法

Last updated at Posted at 2020-09-18

Maps JavaScript API を使うとき、APIキーが心配

【ご注意】本件の記事は、「HTTP リファラー(ウェブサイト)」による制限を否定するものではありません。Google 公式が推奨しているとおり、リファラー(ウェブサイト)による制限は必須です。それに加えAPIキーを公開しない方法が無いものかと考えたのがこの記事です。

Google は、公式サイトで API キーをコードに直接埋め込まないでくださいと言っている割には、[公式サンプル]のコーディングが以下の様になっていて、堂々とHTMLの中にYOUR_API_KEYが登場している。
これでwebページ作ったら世界中にAPI キーを公開してしまうことになる。まるで、堂々とフリチンで公道を歩いている様な状態。公式サンプルは裸の王様か?

<script defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

一応 Google のドキュメント[API キーの制限を適用する]には「HTTP リファラー(ウェブサイト)」による制限が必須だと書いてはあるが、これだけでは非常に心許ない。
皆さんご存じの通り、ウエブページの名前なんてローカルにwebサーバー建てて hosts をいじれば簡単に詐称できるし・・・(私はそんなことやってませんよ。念のため)
もちろん、知らない間に課金されないように、[API 使用の上限設定]は実施しているが、どこかの誰かにAPIキーを勝手に使われて100万回とかアクセスされたらどうしよう?と思うと夜も眠れない・・・

APIキーは見えないところに隠そう

やっぱりAPIキーは、HTMLで公開したくない!!
ということで CGI を使って API キーをサーバーの中に隠しておくことにしました。

1.環境変数にセット

CGI にはAPIキーを環境変数にセットした状態で渡します。私の環境は nginx + fcgiwrap で CGI を動かしているので、/etc/nginx/fcgiwrap.conf の一番下に以下の様にセット。

fcgiwrap.conf
location /cgi-bin/ {
    ・・・・・・
    fastcgi_param GOOGLE_MAPS_API_KEY  YOUR_API_KEY; <=YOUR_API_KEYを自分のキーに置き換えてください
}

ここは、皆さんの環境(apacheなど)毎に設定方法が異なるので、ご自分の環境に合わせて設定してください。

2.CGI を用意

方針としては、公式サンプルの src="https://maps.googleapis.com/maps/api/js の部分を CGI で置き換える。
私の環境では python を使っているので、こんな感じになります。

getapijs.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import os
url = 'https://maps.googleapis.com/maps/api/js' # 公式サンプルの HTML が src= で読んでたurl
key = os.environ['GOOGLE_MAPS_API_KEY'] # 環境変数に入っている APIキーを取り出す
mysrc = url + "?key=" + key # url に APIキーを連結する
response = requests.get(mysrc) # google マップのサイトにアクセスして src を持ってくる
print("'Content-Type': 'text/javascript; charset=UTF-8'") # HTML に返してあげるためのヘッダー
print("")
print(response.text)

この部分も皆さんの環境毎に異なる部分なので、ご自分の使える言語で記述してください。
要は、サーバーの環境変数からAPIキーを持ってきて、url 指定して google のサイトから javascript を頂戴するということです。ヘッダーの部分は、'Content-Type': 'text/javascript; charset=UTF-8' にしましょう。

3.javascript の window.onload で CGI を呼ぶ

main.js
function initMap() {
    // 公式サンプルの内容と同じ
    // Initialize and add the map
    // The location of Uluru
    var uluru = {lat: -25.344, lng: 131.036};
    // The map, centered at Uluru
    var map = new google.maps.Map(document.getElementById('map'), {zoom: 4, center: uluru});
    // The marker, positioned at Uluru
    var marker = new google.maps.Marker({position: uluru, map: map});
}
window.onload = function() {
    // ページを表示した後に、実行したい処理を書く。ここからが今回のポイント!
    fetch("/cgi-bin/getapijs.py").then(res=>{
        // CGI 実行して、結果の TEXT だけを次にパスする
        return res.text();
    }).then(mytext => {
        // 受け取った javascript を EVAL で実行する。
        eval(mytext);
    }).then(() => {
        // 実行後の処理。公式サンプル HTML が &callback= でコールしていた部分
        initMap();
    }).catch(() =>{
        // お好きなエラー処理をどうぞ
    });
}

HTML には、ヘッダー部分に <script src="main.js"></script> を記載してます。この辺の流儀は人によって違うところなので、お好きなスタイルで良いと思います。
要は、HTML の要素を読み込んだ後(サンプルHTMLの defer の部分。私の例では window.onload)に、CGIを実行して javascript をTEXTで受け取りEVAL で実行する、という手順です。
##これで安心して眠れるか?
APIキー は環境変数の中にしかないので、ソースをGITHUBで公開しても問題ないし、WEBサイトのユーザーが Chrome のデベロッパーツールで HTML や JS を見ても、APIキーは見つからない。
公式サンプルが堂々とフリチンで公道を歩いているのに比べれば、奥ゆかしい出来上がりになっています。
唯一、気持ち悪いところがあるとすると「邪悪な EVAL」を使っていることです。邪悪なwebページだと思われてしまうかもしれない・・・
EVAL が禁じ手として封じられている方は今回の手法は使えませんが、APIキーを公開の場に晒すのはEVAL使うよりも危険だと思います。止めましょう。会社でEVAL禁止されている人は諦めて JAVA で重いアプリ作ってください。私は軽くHTML + javascript + python で行きます。

ご参考

index.html
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
      }
    </style>
    <title>Hello World</title>
    <script src="main.js"></script>
  </head>
  <body>
    <h3>My Google Maps Demo</h3>
    <!--The div element for the map -->
    <div id="map"></div>
  </body>
</html>

なお、こちらの記事を参考にさせて頂いています。
[私がよく使うJSからの外部JSの読み込み方法]

こちらのwebsiteもよろしくお願いします。
[[初心者のためのWEBシステムのインフラ構築]]
(https://olto3-sugi3.tk/ja/index.html)

28
30
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?