APIのバックドア

にメンテナンス済み

kintone で API を使用する際、API を介してアクセスする各アプリの権限は、そのアカウントに対するアクセス権限に依存します。

例えば、在庫マスターアプリと在庫一覧アプリが存在し、従業員 A さんは在庫一覧アプリにのみアクセスできる設定がされているとします。

この場合、A さんのアカウントで実行された JavaScript にも同様のアクセス権限が適用されるため、在庫マスターアプリにアクセスするような JavaScript が実行されたとしても、アクセスすることができずエラーとなります。

このため現在の仕様では、JavaScript からだけアクセスしたい場合でも、そのアカウントにアクセスできる権限を付与する必要があります。

しかし、それぞれのアカウントにアプリは表示したくないけど、API だけ利用したい。(ユーザは閲覧することができないが、内部的にはアクセスしたい)といった場合もあるかと思います。

今回はこの対処方法を紹介します。

チェック

が本来想定している仕様から外れた操作になるため、アップデートにより突然実行できなくなる可能性があります。十分注意してご利用下さい。

結論

まず結論からお伝えすると、kintone JavaScript API のkintone.proxyメソッドを使って、同ドメインの REST API にアクセスすることで実現可能です。

公式の cybozu developer network には、

※APIトークンはREST APIを実行するためのトークンであるため、JavaScript API内では利用できないので注意してください。

API トークンを使ってみよう

とありますが、同じく kintone が用意している proxy API を使用すれば動作します。

kintone REST API の認証方法について

kintone REST API の認証方法には ID、パスワードを使う方法と、API トークンを使用する方法があります。

今回の例に関わらず、セキュリティリスクを抑えたいのであれば、REST API を利用する場合は API トークンによる認証を使うべきです。

API トークンについて

2014 年 6 月までは、REST API における認証には、ユーザ ID、パスワードを使う他ありませんでした。現在はその代わりに、アプリ単位で発行される API トークンを使用することでも、API を利用できるようになっています。

API トークンを利用することで、より的を絞った使用が可能になります。

公式にも記載されていますが、API トークンを使うことで、以下のようなメリットがあります。全て、機能を絞ることによるセキュリティリスクの軽減と言えます。

  • ユーザ ID とパスワードが必要ない
  • 限られたアプリにのみ、REST API を実行できる
  • 実行できる REST API の種類を制限することができる

ID、パスワードによる認証方法だと、どうしてもアカウント情報が分散されてしまうため、メンテナンス性も、セキュリティもあまりよくありません。全権限を使用したい場合でも、基本的には API トークンを利用した認証方法が望ましいと思います。

アクセス権限のないアプリにアクセスする方法

本題ですが、冒頭でお話した、それぞれのアカウントにアプリは表示したくないけど、API だけ利用したい

といった場合の実装方法です。

/**
 * kintone.proxyを使用して、権限のないアプリにアクセスします
 * @param {{ uri: string; method: "GET" | "POST" | "PUT"; param: any; apiToken: string }} props 各パラメータ
 * @return { Promise<any> } REST APIの実行結果
 */
const useBackdoor = (props) => {
  const { uri, method, param, apiToken } = props;

  const header = { 'X-Cybozu-API-Token': apiToken };
  let uri = kintone.api.url('/k/v1/record', true);
  let body = '';
  if (typeof param === 'string') {
    uri += encodeURI(param);
  } else {
    header['Content-Type'] = 'application/json';
    body = param;
  }

  return kintone.proxy(uri, method, header, body);
};

今回のコードではグローバル変数の kintone に関数を追加していますが、通常の javascript API のように即時関数の中だけで関数を定義し利用しても構いません。

処理としては、kintone から一度外に出て、別の kintone にアクセスするようなイメージです。

#kintone #JavaScript