ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

NCMB用デスクトップアプリで権限管理を実装しました

Web技術でデスクトップアプリケーションが作れるElectronとJavaScript SDKを使い、社内などで使えるNCMBを運用するためのツールを作ります。前回はごく基本的な認証まで行いましたので、今回は権限管理の実装方法と利用法を紹介します。

権限管理の実現方法

権限管理はNCMBのロールを使っています。そのためあらかじめ幾つかのロールを作成しておきます。今回はAdministrator(管理者)とManager(マネージャ)というロールを指定しています。

var ary = ['Administrator', 'Manager'];

利用するロールをすべて取得する

まず最初にロール情報をすべて取得する必要があります。複数の非同期処理になりますので、Promiseを使って配列で返します。実際の処理はncmb.Roleを検索しているだけです。

var getAllRoles = (ncmb) => {
  var promises = [];
  var ary = ['Administrator', 'Manager'];
  for (i in ary) {
    promises.push(new Promise((res, rej) => {
      ncmb.Role.equalTo("roleName", ary[i])
        .fetch()
        .then(role => {
          res(role);
        })
        .catch(err => {
          rej(err);
        })
    }));  
  };
  return Promise.all(promises);
};

権限ごとにその権限を持っているかチェックする

ユーザ自身が特定のロールに属しているかどうかを取得するメソッドはJavaScript SDKの中にはありません。そこで○の記事を参照に、次のように実装します。これはNCMBオブジェクトを拡張する関数です。

var extend = (ncmb) => {
  ncmb.User.isBelongTo = function(role) {
    me = ncmb.User.getCurrentUser();
    return new Promise(function(res, rej) {
      ncmb.request({
        path: "/"+ncmb.version+"/users", 
        query: {
          where: JSON.stringify({
            "objectId": me.objectId,
            "$relatedTo":{
              "object":{
                "__type":"Pointer",
                "className":"role",
                "objectId": role.objectId
              },
              "key":"belongUser"
            }
          })
        }
      })
      .then(function(ary) {
        var json = JSON.parse(ary).results;
        res(json.length == 1);
      })
      .catch(function(e) {
        rej(e);
      });
    })
  }
  return ncmb;
}

そしてこの関数をNCMBのインスタンスを作成する際に実行します。

this.ncmb = extend(new NCMB(this.application_key, this.client_key));

このようにして目的のメソッドを追加します。

ではこのメソッドを使って各権限ごとに所属しているかどうかをチェックします。こちらも非同期でデータを取得するのでPromiseを使います。元々のロール取得自体が非同期になるため、全体もPromiseで囲む必要があります。

var checkRole = (ncmb) => {
  var promises = [];
  var user = ncmb.User.getCurrentUser();
  return new Promise((res, rej) => {
    getAllRoles(ncmb)
      .then( roles => {
        for (var i in roles) {
          promises.push(new Promise( (res1, rej1) => {
            let role = roles[i];
            ncmb.User.isBelongTo(role)
              .then( bol => {
                if (bol) {
                  res1(role);
                } else {
                  res1(null);
                }
              })
              .catch(err => {
                res1(null);
              })
          }));
        }
        Promise.all(promises)
          .then((roles) => {
            res(roles.filter( role => {
              return role != null;
            }));
          })
      });
  })
};

最後、権限がないデータを削除しておきます。

res(roles.filter( role => {
  return role != null;
}));

認証後に実行

ではこの処理を認証後に利用します。こちらはごく短くて済みます。

checkRole(app.ncmb)
  .then( roles => {
    app.user.roles = roles;
    var msg = `あなたの権限は [${roles.map( role => role.roleName).join(",")}] です`
    setMessage(app, msg, 'success');
  });

このように実装することで、ログイン時に自分の所属グループが表示されます。

利用法

まずJavaScript側で次のように実装します。ロールを配列に変換し、ロール名が存在するかどうかでチェックしています。

var app = {
  :
  methods: {
    hasRole(roleName) {
      if (!this.user || !this.user.roles)
        return false;
      return this.user.roles.map( role => role.roleName).indexOf(roleName) > -1
    },
    :
  }
}

次にHTML側での利用法ですが、次のように簡単に使えます。

<div v-if="hasRole('Administrator')">
  <p>管理者用機能はこちら</p>
  <button>ユーザ管理(ダミー)</button>
</div>

このようにして管理者権限があるかどうかをチェックできます。


権限チェックができれば担当者の権限ごとにメニューの出し分けを行ったり、機能を使えないように制御するのにも使えます。今回のコードはNCMBMania/ElectronNCMBにアップロードされていますので、参考にしてください。このコードをベースにすれば自社用のmBaaS管理ツールを作るのもさほど難しくないでしょう。