プログラムから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とサーバサイドで連携するのは難しくありません。ぜひ試してみてください。