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

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

署名をサーバで行えばニフティクラウド mobile backendをWebアプリでも使えます

ニフティクラウド mobile backendではiOS/Android/JavaScript SDKを提供しています。いずれのSDKにおいてもアプリケーションキーとクライアントキーの2つでアクセスする仕組みになっています。

そのためWebアプリケーションではHTMLまたはJavaScriptソース中にアプリケーションキー、クライアントキーの両方を記述するため、そのまま公開するのはセキュリティ上好ましくありません。

そこでサーバサイドの仕組みをちょっとだけ使ってJavaScript SDKでも安全にニフティクラウド mobile backendにアクセスできるようにしてみたいと思います。

仕組み

現在の仕組みは簡単に言うと次のようになっています。

HTML/JavaScript内に書かれたアプリケーションキー、クライアントキーを使って署名処理を行い、ニフティクラウド mobile backendと直接やり取りができます。これによってMonacaなどでもニフティクラウド mobile backendが使える仕組みです。

それを

このような形にします。つまりWebブラウザからサーバにメッセージを投げて、それを使ってサーバサイドで署名を作成します。そしてその署名を使ってニフティクラウド mobile backendとやり取りするという形です。直接やり取りするのに比べると若干手順が増えていますが、これによりWebアプリケーションでも安全にニフティクラウド mobile backendが使えるようになります。

JavaScript SDKの修正

2014年06月現在、JavaScript SDKの最新版は1.2.1となっています。まずこちらを修正します。具体的には署名を生成している部分、 NCMB._createSignature になります。

こちらの処理の最後の部分、署名を生成している部分を変更します。

var hash = CryptoJS.HmacSHA256(forEncodeString, _clientKey);
var signature = CryptoJS.enc.Base64.stringify(hash);
return signature;

このSHA256でハッシュ化している部分においてクライアントキーが使われています。ここをJavaScriptではなく、サーバサイドに置き換えます。

return NCMB._ajax(
  null,
  null,
  "POST",
  "/sign",
  {forEncodeString: forEncodeString},
  "",
  "");

このようにすることで署名する文字列である forEncodeString を自前のサーバに送信します。返却値として、署名された文字列が受け取れることを期待します。POSTにしているのは外部のサーバから実行されないようにするためです。

後は生成された署名を受け取った後の処理や、クライアントキーがないことによるエラー判定を除外します。

サーバ(Sinatra)

サーバの処理としてはハッシュ化し、Base64でエンコードするだけです。今回はSinatraの例を紹介しますが、大抵のプログラミング言語で簡単に書けると思います。

set :root, File.dirname(__FILE__)
set :public_folder, Proc.new { File.join(root, "public") }
post '/sign' do
  content_type :json
  CLIENT_KEY = 'your_client_key'
  json = JSON.parse(request.body.read)
  {signature: Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), CLIENT_KEY, json["forEncodeString"])).strip()}.to_json
end

受け取った文字列をサーバ側にしかないクライアントキーでハッシュにし、それをBase64エンコードします。後はできあがった文字列をJSONでWebブラウザに返しています。

デモ

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

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="javascripts/ncmb-1.2.1.js"></script>
<script type="text/javascript">
  NCMB.initialize("application_key");
</script>

アプリケーションキーのみで初期化しています。

実際の使い方はサンプルにある通りで変わりません。

var TestClass = NCMB.Object.extend("TestClass");
var testClass = new TestClass();

var query = new NCMB.Query(TestClass);
query.equalTo("message", "test");
query.find({
    success: function(results) {
        if (results[0] != null){
            alert(results[0].get("message"));
        } else {
            testClass.set("message", "Hello, NCMB!");
            testClass.save();
            console.log("Saved!");
        }
    }
});

実行結果は次のようになります。

アプリケーションキーはニフティクラウド mobile backendへアクセスする時のヘッダーとして使いますので表示しておく必要がありますが、クライアントキーは署名時にしか使っていませんのでサーバサイドに隠蔽しても問題ありません。これでWebアプリケーションにおいてもニフティクラウド mobile backendが使えるようになります。

ということはスマートフォンアプリと共通のアプリケーションを使ってチャットをしたり、JavaScriptだけでサーバサイドへのデータ保存を含めた高度なWebアプリケーションが開発できるようになるということです。

また、サーバサイドの処理は見ての通り簡単ですので、既存のWebサーバに組み込んで使うこともできるでしょう。

今回のコードはGitHubへアップしてあります。ぜひ参考にしてください。

f:id:mbaasblog:20180927104348p:plain