2020-07-13に更新

【GAS】コードにAPIトークンやIDのベタ書きを避ける!(プロパティサービスの活用)

GAS

はじめに

GASでの開発でGithubリポジトリと連携する方法について書きましたが、リポジトリにプッシュする前に、一般に公開しないほうが良い情報が入っていないか気をつける必要があります。例えば、

  • APIトークン
  • メールアドレス
  • なんかのパスワード
  • 特定のIDやURL

これまでコードにLINE messanger APIのチャンネルアクセストークンや自身のメールアドレス、LINEのIDなどをベタ書きしており、Githubのリポジトリにアップする際にどうするのが正しいのか悩みました。リポジトリをprivateに設定すれば大丈夫かな?とかやってみたんですが、なんか落ち着かないしスマートじゃない気が。

調べてみると、どうやらGASでは「プロパティ」として公開したくない情報を管理できるやり方があるようです。
またメンターさんに教えていただいたところによると、一般的には秘匿情報を

  • プロパティファイルに記述する
  • 環境変数に入れる

とするのが対策になってくるようです。どの言語でも関係なくこの考え方は理解しておく必要がありそうですね(個人の趣味レベルでもセキュリティ意識は大事だと思う)。

というわけで今回はGASのプロパティサービスを活用することで対応してみたので、それについてまとめてみました。

GASのプロパティサービスとは

イメージ

  • APIトークンやメールアドレスなど一般に公開したくない情報をコードに書く必要がある!
  • そんな時にコードにこれらの情報をベタ書きせず別の場所(プロパティストア)に入れておいて、コードではそこから情報を取り出す命令だけ書いておく(プロパティサービス)。
  • これによって隠したい情報を見れないようにして安全に管理できるよ!

    用語
    ざっくり解説

    プロパティストア
    IDなどの公開したくない情報を格納しておく場所のこと。情報に名前をつけて格納しておくことができる。権限がないと中身を見ることはできない。

    プロパティサービス
    プロパティストアに格納した情報をGASスクリプトから取り出したり編集したりすることができる仕組み。PropatiesServiceやPropertiesなどをコードに書くことで色々できる。

誤解を恐れずわかりやすさ重視でまとめるとこんなイメージです。
(詳細は参照リンク1がとてもわかりやすく大いに参考にさせていただきました)

ちなみにプロパティストアにも「スクリプトプロパティ」「ユーザープロパティ」「ドキュメントプロパティ」と3種類ありますが、詳しくはここでは割愛。初めのうちは「スクリプトプロパティ」だけを考えて大丈夫でしょう。

実装手順

具体的に実装してみます。とってもかんたん。

1.問題のコード

例えばこういうコード。

var ACCESS_TOKEN = "hogehoge1234......";
var calendar = CalendarApp.getCalendarById("hogehoge");

このAPIトークンの中身(hogehoge1234......の部分)はGithubに公開したりブログに書いちゃったりすると誰かに使われてしまう可能性がありそうです。
またカレンダーID(hogehoge)も個人情報なので出来れば隠したいですね。

2.プロパティを登録する

詳細は参照リンク1を参考に。

(1)GASのスクリプトエディタのメニューで、「ファイル」>「プロジェクトのプロパティ」を開く
(2)「スクリプトのプロパティ」タブを選択
(3)「+行を追加」をクリック
(4)左の欄に値を取り出す時に使う名前(キー)、右の欄にAPIトークンなどの値を入れて「保存」をクリック

スクリーンショット 2020-02-08 22.14.59.png

この名前の付け方は何でも良いのですが、一目で何を意味しているのかわかる名前にするのが良いですね。
ここでは「アクセストークン」と「カレンダーID」をそれぞれ登録しておきましょう(参考画像はちょっと違うプロパティを登録してますがすんません)。

※(余談)変数に使用する記号やキャメルケースorスネークケースなどあるので、一貫した命名規則を簡単に学んでおくと名付けで迷うことが無くなるかと思います。
僕はJavascriptの命名規則の一つとしてざっくり「変数名はキャメルケース」「定数名はスネークケース」と学んだので、今回のプロパティは定数と考えてスネークケースで名付けてあります(詳しくは調べてみてね)。

3.登録したプロパティをコードに記述する方法

詳細は参照リンク2を参考に。

プロパティストアの登録が終わったら、問題のコードを書き換えてみます。

var ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty("ACCESS_TOKEN");
var calendar = PropertiesService.getScriptProperties().getProperty("CALENDAR_ID");

最初のコードと全く同じ内容になるのですが、うまく情報を隠して記述することができました!
ただこれだと少し冗長なので次のようにスッキリと書くこともできます。
(プロパティが2つだけだと余計長くなってる感じですが…。プロパティを複数使う場合はだいぶスッキリするはずです)

var prop = PropertiesService.getScriptProperties().getProperties();

var ACCESS_TOKEN = prop.ACCESS_TOKEN;
var calendar = CalendarApp.getCalendarById(prop.CALENDAR_ID);

解説・補足

最終的に書き換えたコードの解説をざっくりとしてみます。

var prop = PropertiesService.getScriptProperties().getProperties();

まずプロパティサービスを使うためには、PropertiesServiceというクラスを使用します。
次にgetScriptPropertiesというメソッドを使用して、プロパティストアに登録したスクリプトプロパティ達を取得します。そこからgetPropaties()というメソッドを使うことで、変数propにオブジェクトとしてプロパティ達をセットしています。
(このpropには登録したプロパティ(キーと値のセット)が全部入っている、というイメージですかね)

var ACCESS_TOKEN = prop.ACCESS_TOKEN;
var calendar = CalendarApp.getCalendarById(prop.CALENDAR_ID);

登録したAPIトークンやIDなどの値を実際に取り出すには、先ほど用意したprop変数を使ってprop.キー名という形で自由に取り出すことができます。やったね!

クラスやメソッドは色々あるので、詳しくは公式ドキュメントを参考に。
なかなか初学者の方にとっては慣れるまではドキュメントの見方が分からず難しいかと思うので、少し慣れた段階や詰まった時に見るようにするといいかもしれません。僕もまだ苦手です。
Properties Service  |  Apps Script  |  Google Developers

あとがきMEMO

どうしても独学ベースだと、セキュリティ面まで意識するのってなかなか難しいんじゃないでしょうか(自分だけ?)
今回のような「秘匿情報を別の場所に格納しておく」という視点は当たり前のことなのかもしれませんが、調べていて目からウロコでした。
今回具体的なGASのプロパティサービスの使い方を書きましたが、それだけに限らない大事な視点だなーと思ってまとめてみました。抽象的な概念と具体的な使い方をセットで覚えておくと理解が深まりますね。

参考にしたサイト

ツイッターでシェア
みんなに共有、忘れないようにメモ

Massa

北海道でアプリ制作に取り組んでるノンプログラマな農夫。仕事や日常生活で感じる小さな不便を解消すべく趣味と実益を兼ねて遊んでます ■Python・GAS + LINE bot

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント