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

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

様々な言語からmBaaSを扱うために署名作成アルゴリズムを考える【Dart編】

f:id:mbaasdevrel:20190702184813p:plain

プログラムからmBaaSを操作する際にはAPIを利用しますが、その時に肝になるのが署名文字列の作成です。パスなどをつなげて、SHA256でハッシュ値を作ったりと非常に面倒な処理が必要です。

アプリ側であればSDKを使ってもらえれば問題ありません。問題はサーバサイドで、オフィシャルではNode.js、非公式ではRubyとPHPくらいしかライブラリがありません。

そこで今回は一番面倒と思われる署名作成処理について、他の言語での実装方法について解説します。今回はDartです。

必要な引数について

署名を作成する際には以下の情報が必要です。

変数 名前 説明
method HTTPメソッド GETやPOSTといった文字列です
fqdn FQDN 通常はmbaas.api.nifcloud.com、スクリプトの場合はscript.mbaas.api.nifcloud.comになります
path リクエストするAPIのパス /2013-09-01/classes/TestClassなどです
queries クエリストリング クエリストリングです。今回はマップで作成しています
applicationKey アプリケーションキー 管理画面で取得できるアプリケーションキーです
signatureMethod シグネチャメソッド HmacSHA256という文字列固定です
signatureVersion シグネチャバージョン 2という文字列固定です
timestamp タイムスタンプ APIリクエスト時の時間です
clientKey クライアントキー 管理画面で取得できるクライアントキーです

ライブラリのインポート

まずは必要なライブラリをインポートします。今回はCUIで動かします。

import "dart:collection";
import 'dart:convert';
import 'package:crypto/crypto.dart';

生成前の変数について

まず上記の変数情報を揃えます。各値は検証のため、REST API リファレンス : シグネチャの生成方法 | ニフクラ mobile backendに合わせています。

const method = 'GET';
const fqdn = 'mbaas.api.nifcloud.com';
const path = '/2013-09-01/classes/TestClass';
const queries = {
  'where': {
    'testKey': "testValue"
  }
};

const applicationKeyName = 'X-NCMB-Application-Key';
const applicationKeyValue = '6145f91061916580c742f806bab67649d10f45920246ff459404c46f00ff3e56';
const clientKeyValue = '1343d198b510a0315db1c03f3aa0e32418b7a743f8e4b47cbff670601345cf75';

const signatureMethodName = 'SignatureMethod';
const signatureMethodValue = 'HmacSHA256';
const signatureVerionName = 'SignatureVersion';
const signatureVerionValue = '2';
const timeStampName = 'X-NCMB-Timestamp';
const timeStampValue = '2013-12-02T02:44:35.452Z';

メソッド、FQDN、パスを配列に入れる

最終的に改行繋ぎの文字列を作るために、まずはマップに入れておきます。マップはSplayTreeMapを使って自動的にソートを行います。そして最後にsignatureStringにメソッドやFQDNといった情報を入れます。

var hash = new SplayTreeMap<String, String>();
hash[applicationKeyName] = applicationKeyValue;
hash[signatureMethodName] = signatureMethodValue;
hash[signatureVerionName] = signatureVerionValue;
hash[timeStampName] = timeStampValue;
queries.forEach((key, params) {
  hash[key] = Uri.encodeComponent(jsonEncode(params));
});
var ary = [];
hash.forEach((key, value) {
  ary.add('$key=$value');
});
var signatureString = [];
signatureString.add(method);
signatureString.add(fqdn);
signatureString.add(path);
signatureString.add(ary.join('&'));

署名を生成する

署名を生成するのはHMAC SHA256でハッシュを生成し、それをBASE64でエンコードするだけです。処理としては以下のようになります。

var converter = new Utf8Encoder();
List<int> key = converter.convert(clientKeyValue);
List<int> messageBytes = converter.convert(signatureString.join("\n"));
var hmacSha256 = new Hmac(sha256, key);
var digest = hmacSha256.convert(messageBytes);

var str = base64.encode(digest.bytes);

これで生成される文字列がドキュメントと同じ署名になります。

まとめ

この処理で署名生成処理が完了します。署名され作れればmBaaSとサーバサイドで連携するのは難しくありません。ぜひ試してみてください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。