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

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

クライアントキーを隠蔽して安全にmBaaSを使ってみる

mBaaSではアプリケーションキーとクライアントキーを組み合わせて使いますが、もしこの2つのキーが漏洩するとアプリを自由に(アクセス権限がないデータについては)操作できるようになります。コンパイル系のプログラミング言語では安全ですが、Webアプリケーションなどで使うのは難しいかと思います。

そこで今回はJavaScript SDKの署名生成部分をサーバサイドで行うことによってmBaaSを安全に使えるようにしてみたいと思います。以前、JavaScript SDK ver.1については行いましたが、今回はそのver. 2版になります。

変更点

変更するのは以下の3つのファイルです。

  • lib/request.js
  • lib/signature.js
  • lib/ncmb.js

lib/request.js

このファイルはシグネチャ生成メソッドを呼んでいます。シグネチャをサーバサイドで行うと言うことは非同期処理になるということなので、署名生成処理以下をPromiseで行うようにします。

以下のようにすることで、sigという変数に対してシグネチャが入ってくるようにします。

return (this.createSignature || require("./signature").create)(
  parsedUrl.format(), method, opts.query || "", timestamp,
  opts.signatureMethod || self.signatureMethod,
  opts.signatureVersion || self.signatureVersion,
  opts.fqdn || self.fqdn,
  opts.apikey || self.apikey, self.clientkey || self.clientkey
).then(function(sig) {
  :
  }).catch(function(err) {
    console.error("Error: "+err);
  });

lib/signature.js

このファイルは実際にシグネチャを生成しています。変更点としては、

  • 文字列ではなくPromiseオブジェクトを返す
  • Ajaxで署名生成処理を行う
  • リクエストがうまくいったらresolveを呼ぶ

となります。

return new Promise(function(resolve, reject){
  :
  var r = request.post(signature_url);
  r.send({forEncodeString: sigStr})
  .end(function(err, res){
    if (err || !res.ok) {
      return reject(err);
    }else{
      return resolve(res.body.signature);
    }
  });
});  

今回はmoongift/ncmb-serverを使っています。これは送られた文字列(署名すべき文字列)をクライアントキーを使ってハッシュ化し、それをBase64エンコードしているだけです。

{signature: Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), CLIENT_KEY, json["forEncodeString"])).strip()}.to_json

これでシグネチャが受け取れるようになりました。

lib/ncmb.js

最後にncmb.jsですが、これはクライアントキーがなくともエラーにしないという処理にします。

if(!apikey){
  throw new Error("apikey required");
}

また、optionとしてsignature_urlという署名を行うURLを渡せるようにします。

this.signature_url    = config.signature_url || null;

試してみる

では実際に試してみます。HTMLは次のようになります。

<script>
  function onReady() {
    var application_key = 'c44...00d';
    var ncmb = new NCMB(application_key, null, {"signature_url": "http://localhost:4567/sign"});
  }
  document.addEventListener("DOMContentLoaded", onReady, false);
</script>

signature_urlは今回の場合、必須になります。2番目のnullはクライアントキーです。後は普通のJavaScript SDKと同じように使えます。

var D = ncmb.DataStore("d");
var d = new D;
d.set("test", "hello");
d.save().then(function(d) {console.log(d)});

このようにクライアントキーを隠蔽することで、Webアプリケーションにおいても安全にmBaaSが利用できるようになります。ぜひお試しください。なお、今回のコードはmoongift/ncmb_jsにアップしてあります。