NCMBとMONACAを使ってアプリ開発(グループごとにログイン情報が見れるようにする)


今回したいこと

  • 特定のグループがある
  • グループごとに見れるデータを分ける
  • 他のグループのデータは見れない
  • グループに所属させるのは、すでにログインしているユーザーが他のユーザーに許可を与える

アクセス許可についてまとめる

  • NCMBのroleクラスを利用する
  • roleクラスの「belongUser」カラムに、ユーザーを所属させる
  • 所属させたrole名を、表示絞りたいクラスの「レコード」の「ACL」に付与する。すると、「role」に所属していないと表示されなくなる

つまり、グルーピング用の「role」を作成させ、データ作成時にはその「role」を「レコード」の「ACL」にsetしてあげればいい。
グループに人を入れたいときは、グループに所属している人が入れてあげればいい。
※そのために、ユーザー作成時にはACLを全許可にする必要がある。

それっぽい図:

作ってみる

1.グループを作る

まず第一に以下のソースでグループを作れるようにする。

roleを作ってグループにする
function makeRoleTest(){
    var makeNewRole = new ncmb.Role($('#rolenametest').val());
    makeNewRole.save()
                .then(function(){
                    alert("success new role :" + $('#rolenametest').val())
                })
                .catch(function(err){
                    alert("err makeRoleTest")
                });
}

2.グループに所属させる

ここでは「ログインユーザー」を所属させている。けど、本当はここで、[ncmb.User.getCurrentUser();]の部分で、所属させたいユーザー情報をUserから取得して渡すことがいい。

グループに所属させる
//userをroleに所属させる
function belongUserForRoleTest(){
    //ログインユーザーをuserオブジェクトに入れる
    var user = ncmb.User.getCurrentUser();
    //既存のロールを検索
    ncmb.Role.equalTo("roleName",$('#rolenametest').val())
             .fetch()
             .then(function (role){
                if (JSON.stringify(role) === "{}") {
                    alert("err no fetch rolename")
                } else {
                    //会員をロールに追加
                    role.addUser(user).update()
                                      .then(function (role){
                                          alert("Success!! add user:" + user.get("userName") + " for role:" + $('#rolenametest').val())
                                      }).catch(function(err) {
                                          alert("error add user for role")
                    });
                }
            }).catch(function (err){
                alert("please input rolename or login")
            });
}

3.現在存在しているデータに特定のroleアクセス権限を付与する

この例ではすでに登録しているレコードを呼び出してaclを付与しているが、本当はInsert時点(saveメソッドを使ってデータを渡すとき)にaclをsetしてあげることになる。

レコードに特定のroleACLを付与する
//権限を付与する
function addRoleForRecordTest(){
    //aclの状態をどういった形で登録したいかを定義する
    var acl = new ncmb.Acl();
    acl.setRoleReadAccess($('#rolenametest').val(), true) // 入力したロールの読み込みを許可
       .setRoleWriteAccess($('#rolenametest').val(), true) // 入力したロールの書き込みを許可
    //alert(JSON.stringify(acl));

    //setしたいレコードを読み出す
    var testData = ncmb.DataStore("testData");
    testData.fetchAll()
        .then(function(results){
            // テストなんで1個めのデータに付与する。一致するデータが1つのみだと、やりやすい
            var getTestData = results[0];
            // 読み出したレコードに新しくaclを設定する
            getTestData.set("acl", acl);
            //alert(JSON.stringify(getTestData));
            getTestData.update();
            alert("success acl update");
        })
        .catch(function(err){
            alert("Error:no data testdata can't fetch");
        });    
}

まとめ

これを応用したら、グループごとに管理をユーザーだけでできるようになるはず。あとは、操作ミスした場合や、所属をやめたいとき用に、RoleクラスのbelongUserカラムからの削除(remove)をできるようにしてあげえばOK!!

memo

  • role自体もレコードなので、ACL次第で見れる見れないが決まる。けどこっちはACLではなくてFetchのときにequalToでもいいかも。うーん。ACLのほうが安全かな。そうすると、作成時とbelongUser時にACLもセットしていく必要があってちょっとめんどい。

  • はまったこと
    acl.setPublicReadAccess(false) // 全体の読み込みを拒否
    →これをするとなぜかうまくいかない。というか、aclにfalseを与える動作がうまくいかない。なぜだろうか。まあけど、特定のroleにのみtrueを入れるように上書くので、falseを使わないで上書けばいいだけなのでいいや。

参考URL

公式のHPくらいしか参考になるのがなくて切なかった。
http://mb.cloud.nifty.com/assets/sdk_doc/javascript/jsdoc/files/lib_datastore.js.html#l9
http://mb.cloud.nifty.com/assets/sdk_doc/javascript/jsdoc/files/lib_acl.js.html#l5
http://mb.cloud.nifty.com/doc/current/datastore/contents_javascript.html
http://mb.cloud.nifty.com/doc/current/user/manage_privileges_javascript.html