ニフクラmBaaSお役立ちブログ

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

マスタメンテナンス画面を作る(その1)「認証を作る」

mBaaSでは開発者でなくとも使いやすい管理画面を提供していますが、すべての機能が使える分、どれを触れば良いのか分からないと感じてしまう担当者の方も多いようです。また、権限の設定などを間違えるとアプリで使えないデータになってしまう場合があります。

そこで担当者向けの管理画面を別に作るという話は良く聞かれます。限定的な機能だけを提供した、管理画面のサブセット版のようなものです。今回から何回かに分けて、そんな管理画面の作り方を紹介します。今回はまず認証を作ります。

主な機能

今回作る主な機能は次の通りです。

  • 管理者の認証
  • 担当者アカウントの作成
  • 担当者アカウントの認証
  • メニューの出し分け
  • ログアウト

準備

今回はJavaScript SDKを使っています。社内での利用を想定していますので、アプリケーションキーとクライアントキーはそのまま記述してしまいます。Webブラウザだけで動きますので、サーバは不要です。

ライブラリ管理に Bower を使っています。そして、ncmb と bootstrap をインストールしています。

bower install ncmb --save
bower install bootstrap --save

これで準備は完了です。

管理画面での準備

最初の管理者アカウントだけはmBaaSの管理画面で作成してください。また、以下のロールを作成して管理者アカウントを両方に追加しておきます。

  • Administrator
  • Manager

認証

認証処理については管理者、担当者の区別はありません。入力されたユーザ名とパスワードで認証を行います。checkRole関数は管理者かどうかの権限チェックを行います。

$(function() {
  $("#loginForm").on("submit", function(e) {
    e.preventDefault();
    var userName = $(this).find("[name='userName']").val();
    var password = $(this).find("[name='password']").val();
    ncmb.User.login(userName, password)
      .then(function(user) {
        $(".page").addClass('hide');
        checkRole();
      })
      .catch(function(err) {
        showMessage('danger', 'ログインに失敗しました');
      })
  });
});

checkRoleは次のように行います。ログインしている場合に、Administratorに所属しているかチェックします。

var checkRole = function() {
  if (!ncmb.User.getCurrentUser()) {
    changeMenu("login");
    return;
  }
  ncmb.Role.equalTo("roleName", "Administrator")
    .fetch()
    .then(function (role){
      ncmb.User.isBelongTo(role)
    .then(function(result) {
        if (result) {
          changeMenu("admin");
          console.log("所属しています")
        }else{
          changeMenu("manager");
          console.log("所属していません")
        }
      }, function(err) {
        console.log("エラー", err);
      })
    });
};

isBelongToは独自に追加した関数で、次のようになります。

// ユーザが指定したロールに所属しているかチェックします
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);
      });
  })
}

管理者権限がある場合、アカウント作成のリンクを表示します。この仕組みを使えば、より細かくグループに応じた機能提供ができるでしょう。

担当者アカウントの作成

アカウント作成機能は次のようになります。注意点としては、Managerグループを取得して、そのグループにアカウントを紐付けると言うことです。データのメンテナンスはこのManagerグループの権限に紐付く形で作成します。

グループに紐付ける場合はまず、ユーザを作成した後で行う必要がありますので注意してください。

$("#createManagerForm").on("submit", function(e) {
  e.preventDefault();
  var userName = $(this).find("[name='userName']").val();
  var password = $(this).find("[name='password']").val();
  var user = new ncmb.User({
    userName: userName,
    password: password
  });
  
  user.signUpByAccount().then(function(user){
    ncmb.Role.equalTo("roleName", "Manager")
      .fetch()
      .then(function (role){
        role
          .addUser(user)
          .update()
      })
      .then(function (role){
        $("#createManagerForm")[0].reset();
        showMessage('success', 'アカウントを追加しました');
      });
  });
})

メニューの出し分け

メニューは次のグループに応じて分かれます。

  • 未ログイン
  • 担当者
  • 管理者

これはさらに細かく分けることもできるでしょう。

var changeMenu = function(type) {
  switch (type) {
  case "login":
    $(".login-required").hide();
    $(".no-login").show();
    break;
  case "admin":
    $(".admin-required").show();
    $(".login-required").show();
    $(".no-login").hide();
    break;
  case "manager":
    $(".login-required").show();
    $(".admin-required").hide();
    $(".no-login").hide();
  }
};

ログアウト

ログアウト処理は通常の ncmb.User.logout を使いますが、セッションの状態によって403エラーになることがあります。その場合はローカルの localStorage を強制削除して対応します。

$("#logout").on("click", function(e) {
  e.preventDefault();
  ncmb.User.logout()
    .then(function() {
      changeMenu("login");
    })
    .catch(function(err) {
      // ログアウト失敗時
      localStorage.removeItem("NCMB/"+ncmb.apikey+"/currentUser")
      changeMenu("login");
    })
});

ここまでの処理によって担当者ごとの認証処理が完了します。認証処理を使わないと、データのACLが正しく設定できなかったり、誰が操作を行ったのかというログを管理する上でも困るでしょう。

今回までのコードは NCMBMania/DataMaintenance at 0.1 にアップしてあります。参考にしてください。

では次回以降、データメンテナンス部分を作っていきます。