kintoneプラグインで秘匿情報を隠す〜隠蔽方法編〜

著者名:宮倉 宗平(サイボウズ)

目次

はじめに

kintoneプラグインを利用すると、手軽に複数のアプリへ同じ機能を適用できたり、バージョンアップを一括ですべてのアプリに適用できたりといったメリットがあります。
はじめようkintoneプラグイン|kintoneプラグインのメリット

このシリーズではkintoneのプラグインのメリットのひとつ「秘匿情報を隠蔽できるためセキュリティが向上する」点を深掘りします。
前編となるこの記事では、kintoneプラグインで利用できるJavaScript APIを紹介し、デモを交えながらkintoneプラグインを使って情報を隠蔽する方法を解説します。

このような方におすすめ

  • kintoneプラグイン開発を始めてみたい。
  • kintoneプラグインのメリットをもっと詳しく知りたい。
  • kintoneプラグインJavaScript APIの使い方を知りたい。

検証環境

今回の検証では、次の環境でサーバーサイドのアプリを構築します。

  • AWS EC2(Linux)
  • Node.js(Express)

リクエストのヘッダー情報が確認できる環境なら別の環境でも問題ありません(例:Apache + PHPなど)。
このサーバーサイドのアプリにkintone側からリクエストを送り、リクエストの内容を実際に確認していきながら、検証したいと思います。

検証のブラウザーにはGoogle Chromeを使用しています。

検証の流れ

  1. プラグイン上で、 外部APIの実行に必要な情報をプラグインへ保存するAPI(kintone.plugin.app.setProxyConfig()で情報をヘッダーに設定します。
    プラグインの設定側で設定したヘッダーを「ヘッダーA」とします。
  2. カスタマイズ用JavaScriptファイル上で、別の情報をヘッダーに設定します。
    カスタマイズファイル側で設定したヘッダーを「ヘッダーB」とします。
  3. プラグインから外部APIを実行するAPI(kintone.plugin.app.proxy()でサーバー側にリクエストを送信します。
  4. 手順3で送信したヘッダー情報のうち、ヘッダーBの情報だけが閲覧できることを確認します。
  5. サーバー側で、ヘッダーAとヘッダーBの情報を見ることができるかどうかを確認します。
  6. プラグイン側で保存した情報が隠匿されていることを確認できれば成功です。

サーバーサイドのアプリ構築

Node.jsの開発環境は、AWSのEC2のコンソール上で次のコマンドを実行して構築しました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Expressのアプリ雛形を生成する「express-generator」をインストール
npm install -g express-generator

# 「kintone-app」という名前でExpressアプリを生成
express kintone-app

# ディレクトリ移動&パッケージのインストール
cd kintone-app && npm install

# express起動
node ./bin/www

今回は、上記の手順で生成したアプリのうち、「./routes/index.js」のみを使用し、進めていきます。
「index.js」を以下のように編集します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const express = require('express');
const router = express.Router();

// kintoneからのリクエストの受け取り
router.post('/api/data', (req, res, next) => {
  // ログの表示
  console.log(req.headers);
  res.send('send');
});

module.exports = router;

今回は、次のように指定してログを表示することにします。

  • URLのパス:指定のURL/api/data
  • HTTPメソッド:POST

これで、サーバーサイド側の準備は完了です。

Node.js,Expressの詳細に関しては、以下の公式ドキュメントを確認してください。
Express公式ドキュメント (External link)

kintoneプラグインの開発

次に、kintone側で、kintoneプラグインJavaScript APIを用いて、上記で構築した情報を保存していきます。
今回はプラグイン設定画面で情報を保存し、kintoneレコード一覧画面でサーバー側にAPIリクエストを送る簡単なプラグインを作成し、それを用いて実行してきます。
今回使用したサンプルプラグインは miyass/kintoneProxySamplePlugin (External link) で公開しています。

フォルダーの構成は以下のようになっています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kintoneProxySamplePlugin
├── config_css
│   └── 51-modern-default.css
├── config_js
│   └── config.js
├── contents
│   ├── icon.png
│   └── setting.html
├── desktops
│   └── desktop.js
└── manifest.json
kintoneプラグイン設定画面

まず初めに、「setting.html」上にテキストフィールドを作成します。
テキストフィールド内に入力された情報は、 kintone.plugin.app.setProxyConfig() で保存します。
以下がサンプルコードです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--
 * Secure plugin configuration
 * Copyright (c) 2018 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
-->

<div>
  <div class="block">
    <label class="kintoneplugin-label">
        <span id ="container_label">プラグイン設定画面</span>
    </label><br >
    <div class="kintoneplugin-desc">プラグイン上に保存するテキストを入力</div>
    <div class="kintoneplugin-input-outer">
      <input id="inputText" class="kintoneplugin-input-text" type="text">
    </div>
    <div class="block">
      <button type="button" id="check-plugin-submit" class="kintoneplugin-button-dialog-ok">保存する</button>
      <button type="button" id="check-plugin-cancel" class="kintoneplugin-button-dialog-cancel">キャンセル</button>
    </div>
  </div>
</div>

kintoneプラグイン設定用JavaScriptファイル

次に、プラグイン設定画面用のJavaScriptファイル「config.js」を編集します。
設定画面のJavaScriptファイルでは、プラグイン上に情報を保存する処理を記載します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * Secure plugin configuration
 * Copyright (c) 2018 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */

jQuery.noConflict();
(function($, PLUGIN_ID) {
  'use strict';

  $('#check-plugin-submit').on('click', () => {
    const URL = 'こちらにリクエスト先のURLを指定';
    // パスの指定
    const PATH = 'api/data';
    // HTMLのinputFieldのテキスト情報の取得
    const text = $('#inputText').val();
    // 保存したい情報をヘッダーに設定
    const pluginHeader = {
      'CUSTOM-REQUEST-HEADER': text
    };
    kintone.plugin.app.setProxyConfig(URL + PATH, 'POST', pluginHeader, {});
  });

  $('#check-plugin-cancel').on('click', () => {
    history.back();
  });
})(jQuery, kintone.$PLUGIN_ID);

kintoneカスタマイズ用JavaScriptファイル

次にPC上のカスタマイズ用のJavaScriptファイル「desktop.js」を編集します。
kintoneカスタマイズ用JavaScriptファイルでは、レコード一覧画面を開いたときに kintone.plugin.app.proxy() を実行する処理を記述します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 * Secure plugin customize
 * Copyright (c) 2018 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */

(function(PLUGIN_ID) {
  'use strict';

  kintone.events.on('app.record.index.show', (event) => {
    const URL = 'こちらにリクエスト先のURLを指定';
    // パスの指定
    const PATH = 'api/data';
    // 保存したい情報をヘッダーに設定
    const desktopHeader = {
      DESKTOP_HEADER: 'hoge'
    };
    // サーバ側にリクエスト送信
    kintone.plugin.app.proxy(PLUGIN_ID, URL + PATH, 'POST', desktopHeader, {}, (body, status, headers) => {
      console.log(status, body, headers);
    }, (error) => {
      console.log(error);
    });
    return event;
  });
})(kintone.$PLUGIN_ID);
検証用の変数の設定
14
15
16
17
    // こちらが手順2です
    const desktopHeader = {
      DESKTOP_HEADER: 'hoge'
    };

また、今回は上記のようにカスタマイズファイル上でも情報を保存して、以下の変数がコンソール上などでどのように表示されるかを確認します。

  • プラグイン上で保存したpluginHeader変数
  • カスタマイズ環境上で保存したdesktopHeader変数
kintoneプラグインJavaScript APIでリクエストを送信するときの注意点

kintone.plugin.app.proxy()でリクエストを送る場合、このAPIに指定した情報とkintone.plugin.app.setProxyConfig()で保存した情報のうち、次の値を一致させる必要があります。

  • アプリ
  • プラグイン
  • HTTPメソッド
  • APIのURLの前方

詳細は、 保存した情報がリクエストに加わる条件 を確認してください。

検証

では実際に上記の開発環境を用いて検証していきたいと思います。

まず初めに、プラグイン設定画面で、インプットフィールドに、 kintone.plugin.app.setProxyConfig() で保存するテキストを入力します。
今回は、「kintoneProxyTest」とします。

保存した後に、アプリを更新し、レコード一覧画面に戻ると、自動的に kintone.plugin.app.proxy() が実行されます。
レコード一覧画面で開発者ツールを開き、「Network」タグ「XHR」欄にある、今回送ったリクエストのヘッダーを確認しましょう。

上図のように、カスタマイズ上で保存した変数はheadersから確認できますが、プラグイン上で保存した変数は確認出来ないことが分かります。
しかし、Node.js上のコンソールを確認してみると、プラグイン上で保存した変数も確認することできました。

まとめ

このように、以下のkintoneプラグインJavaScript APIをうまく活用すれば、APIトークンなどの重要な情報などをkintoneサーバー上に保存して、必要な時に取得できます。

今回は、検証のためサーバーを構築しましたが、実際によく使われるパターンとしては、SlackやGoogle各種サービスなどといった外部サービスとの連携がとても多いです。

SlackのAPIを使った連携事例は、後編の記事で公開しています。
kintoneプラグインで秘匿情報を隠す〜実践編〜

カスタマイズで外部サービスとの連携するとkintoneをより便利に活用できます。
しかし、アプリに適用するカスタマイズファイルでAPIトークンなどの秘匿情報を記載してしまうと、ブラウザーの開発者ツールからその情報を誰でも見ることができるようになってしまいます。
今回の検証で明らかになったように、kintoneプラグイン上で保存した情報はブラウザーの開発者ツールからは確認できないため、情報の隠匿が可能になります。
安全、確実に運用したいという方は、ぜひプラグイン制作も検討してみてください。

information

このTipsは、2018年11月版kintoneで動作を確認しています。