Server Code の実行ユーザー

Server Code が Kii Cloud 上で実行されるとき、モバイルアプリの場合と同様に、どのユーザーの権限で動作しているかを意識する必要があります。Kii Cloud 内のデータにアクセスするときは、そのデータに設定されている ACL が参照され、アクセスが許可されたユーザーだけが操作を実行できます。Server Code から対象のデータにアクセスする際、アクセスが可能なユーザーにログインしたり、管理者のコンテキストを利用したりすることによって、適切なアクセスを得ることができます。

Server Code では以下のユーザーの権限を扱います。

匿名ユーザー

これは、Server Code が起動した直後の状態です。

ログイン処理を行わず、そのままデータアクセス用の機能を利用します。

モバイルアプリと同様に、Server Code はデフォルトで匿名ユーザーの権限で動作しているため、アクセスできる範囲は限定されます。単純な計算、Kii Cloud 外へのアクセス、アプリケーションスコープの Bucket からの読み込みなどは匿名ユーザーのままでも処理できますが、KiiUser が持つデータにアクセスしたい場合などは、匿名ユーザーによるアクセス以外のいずれかのユーザーの権限が必要になります。

以下は、匿名ユーザーの権限でアプリケーションスコープの Bucket myAppBucket をアクセスする例です(KiiObject の操作例は省略しています)。

function main(params, context, done) {
  // Handle application scope bucket.
  var appBucket = Kii.bucketWithName("myAppBucket");

  done("Success");
}

呼び出し元ユーザー

Server Code が手動実行された場合に限り、モバイルアプリでの呼び出し元ユーザーのアクセストークンを取得できます。このアクセストークンを使って ログイン すれば、呼び出し元ユーザーの権限で Kii Cloud の API を実行できるため、ユーザースコープのデータに容易にアクセスできます。

Server Code がクライアントから手動実行で呼び出された場合、クライアントの実行ユーザーと同じユーザーでログインした状態にできます。Server Hook(トリガー起動)の場合、実行を引き起こしたユーザーと同じユーザーでログインした状態にできます。

いずれの場合も、以下のように getAccessToken() メソッドでアクセストークンを取得し、アクセストークンによるログイン機能を使用します。クライアント側の実装と同様に、各スコープの Bucket を取得して、データにアクセスできます。

function main(params, context, done) {
  if (context.getAccessToken() == null) {
     done("Sorry, we don't allow an anonymous user");
     return;
  }
  KiiUser.authenticateWithToken(context.getAccessToken(), {
    success: function(theUser) {
      // Handle application scope bucket.
      var appBucket = Kii.bucketWithName("myAppBucket");

      // Handle group scope bucket. (You need groupID parameter)
      var group = KiiGroup.groupWithName(params.groupID);
      var groupBucket = group.bucketWithName("myGroupBucket");

      // Handle user scope bucket.
      // You can use getCurrentUser(). It is same as theUser in this code.
      var user = KiiUser.getCurrentUser();
      var userBucket = user.bucketWithName("myUserBucket");

      done("Success");
    },
    failure: function(theUser, errorString) {
      done("Error authenticating: " + errorString);
    }
  });
}

任意のユーザー

Server Code でもユーザー名とパスワードを指定すれば任意のユーザーとしてログインすることができます。ログイン後はそのユーザーの権限で Kii Cloud のデータにアクセスできます。

この方法はアプリケーションスコープの管理用 Bucket を特定ユーザーの権限でアクセスするような設計を行った場合などに応用できます(この方法は設計上の選択肢の 1 つですが、通常は次に説明する 管理者 のコンテキストを使用するほうが容易です)。

function main(params, context, done) {
  // Define the secret account.
  var username = "servercode";
  var password = "123ABC";

  // Authenticate a user.
  KiiUser.authenticate(username, password, {
    success: function(theUser) {
        // Handle application scope bucket.
        var appBucket = Kii.bucketWithName("myAppBucket");

        // Handle group scope bucket. (You need groupID parameter)
        var group = KiiGroup.groupWithName(params.groupID);
        var groupBucket = group.bucketWithName("myGroupBucket");

        // Handle user scope bucket.
        // You can use getCurrentUser(). It is same as theUser in this code.
        var user = KiiUser.getCurrentUser();
        var userBucket = user.bucketWithName("myUserBucket");

        done("Success");
    },
    failure: function(theUser, errorString) {
        done("Error authenticating: " + errorString);
    }
  })
}

管理者

Server Code では、管理者の権限を使ってアプリケーション内のすべてのデータにアクセスできます。管理者の権限を使用する場合は、ログイン中のユーザーとは別に、管理者のコンテキストを使用します(管理者としてログインするわけではありません)。Server Code のエンドポイントの引数には、管理者のコンテキストを取得するメソッドがあります。そのコンテキストに対してユーザー ID やグループ ID を指定すれば、管理者権限でアクセスできるユーザーやグループのオブジェクトを取得できます。

以下のように、getAppAdminContext() メソッドを使って管理者のコンテキストを取得し、そのメソッドから管理者権限での Bucket アクセスができます。

function main(params, context, done) {
  // Get the administrator's context.
  var admin = context.getAppAdminContext();

  // Create a bucket in the application scope.
  var appBucket = admin.bucketWithName("myAppBucket");

  // Create a bucket in a group scope by specifying the groupID parameter.
  var group = admin.groupWithID(params.groupID);
  var groupBucket = group.bucketWithName("myGroupBucket");

  // Create user scope bucket by specifying the userID parameter.
  var user = admin.userWithID(params.userID);
  var userBucket = user.bucketWithName("myUserBucket");

  // Return a value to the caller.
  done(appBucket + "," + userBucket);
}

各スコープに管理者権限でアクセスするためには、必ず getAppAdminContext() メソッドの戻り値(上記のコードでは変数 admin)を経由する必要がある点に注意してください。たとえば、Kii.bucketWithName() メソッドや KiiObject.objectWithURI() を使用すると、アプリケーションスコープの Bucket と Object を取得できますが、これは匿名ユーザーでのアクセスになります。

管理者アクセスで使用できる機能は、アプリ管理者向け機能 を参照してください(リンク先のページでは管理者のコンテキストを取得する処理も含みますが、Server Code では不要です)。JSDoc も参照してください。

また、管理者権限を使ったサンプルコードとして、サーバートリガーで自動的にデータ付与 の例も参照してください。

なお、管理者権限でのアクセスでは、管理者でログインするわけではないため、getCurrentUser() メソッドで管理者トークンを取得できません。上記のコードで実行すると、匿名ユーザーを表す null が取得されます。

アプリ管理者の権限では、セキュリティ低下のリスクも発生する点にご注意ください。通常は、ACL と実行元ユーザーの組み合わせによってデータが守られていますが、管理者権限ではアプリ内の全データにアクセスできます。特に、重要データを扱う場合には、Server Code の入り口で呼び出し元ユーザーやパラメータをチェックするなど、Server Code 側で 不正な呼び出し に対する防御を行ってください。

管理用データ領域の作成

管理者の権限を使うと、ユーザーからは直接アクセスできない管理領域を使った処理を記述することもできます。操作は Server Code を通してカプセル化できるため、ユーザーからの不正なアクセスを防止できます。

まず、アプリケーションスコープに Bucket を作成し、アクセス権の操作によってユーザーからのアクセス権を削除しておきます(必要に応じて スコープのアクセス権を変更 して新たな Bucket の作成そのものも禁止できます)。次に、Server Code で管理者のコンテキストを取得して、その Bucket のデータを読み書きして管理データを操作します。

直接アクセスのリスクについては アプリケーションスコープのデータ もご覧ください。