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

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

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

f:id:mbaasdevrel:20200110154553p:plain

mBaaSにAPIアクセスする際に最もネックになるのが署名文字列の生成かと思います。これまで幾つかのプログラミング言語において、署名生成の方法を紹介してきました。

今回は最近話題になっているFlutterで使われているDartで署名を生成する方法を紹介します。今回はFlutterでも

インポートするライブラリについて

flutterコマンドで生成されたプロジェクトに対して、以下のライブラリを追加しています。

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

必要な変数を準備する

まず署名生成に必要な変数を準備します。アプリケーションキーはREST API リファレンス : シグネチャの生成方法 | ニフクラ mobile backendに記載されているものを利用しています。時刻は現在のものを使うのが望ましいですが、今回は同ドキュメントに記載のものを使っています。

String signatureMethod = 'HmacSHA256';
String signatureVersion = '2';
String applicationKey = '6145f91061916580c742f806bab67649d10f45920246ff459404c46f00ff3e56';
DateTime date = DateTime.parse('2013-12-02T02:44:35.452Z');

これらの変数をMapにまとめます。日付はISO8601形式にしておきます。

Map baseInfo = {
  "SignatureVersion": signatureVersion,
  "SignatureMethod": signatureMethod,
  "X-NCMB-Application-Key": applicationKey,
  "X-NCMB-Timestamp": date.toIso8601String()
};

さらにクエリ文字列を用意します。これもMapとします。

Map queries = {
  "where": {
    "testKey": "testValue"
  }
};

署名用文字列を作る

用意した変数を使って、署名用の文字列を作成します。まずクエリ文字列をbaseInfoに追加します。whereなどはMapになっていますので、jsonEncodeを使って文字列化します。この時、Uri.encodeQueryComponentを使って値をエンコードします。

queries.forEach((key, value) => baseInfo[key] = Uri.encodeQueryComponent(jsonEncode(value)));

baseInfoのキーと値を = で繋ぎます。

List sigList = [];
baseInfo.keys.toList().forEach((key) => sigList.add("$key=${baseInfo[key]}"));

そしてリストをソートします。

sigList.sort();

ソートし終わったら各値を & でつないで一つの文字列にします。これが署名用文字列です。

String queryString = sigList.join('&');

署名する

署名処理に必要なのは以下の情報です。

  • HTTPメソッド(今回はGET)
  • FQDN(mbaas.api.nifcloud.com など)
  • リクエストパス(/2013-09-01/classes/TestClass など)
  • 署名用文字列

署名用文字列はすでに用意したので、他の変数を用意します。

String method = 'GET';
String fqdn = 'mbaas.api.nifcloud.com';
String path = '/2013-09-01/classes/TestClass';

これらの変数をすべて改行で連結します。

String str = [
  method,
  fqdn,
  path,
  queryString
].join("\n");

後はHmacのSHA256でハッシュ化し、BASE64エンコードした文字列が署名になります。

String secret = '1343d198b510a0315db1c03f3aa0e32418b7a743f8e4b47cbff670601345cf75';
List<int> key = utf8.encode(secret);
Hmac hmac = new Hmac(sha256, key);
String sig = base64Encode(hmac.convert(str.codeUnits).bytes);
debugPrint(sig);

結果はドキュメントと同じ AltGkQgXurEV7u0qMd+87ud7BKuueldoCjaMgVc9Bes= になります。

まとめ

署名文字列が正しく作れれば、次のステップとしてリクエスト処理を行えるようになります。DartはJavaScriptやSwiftに似せて書けるので、習得はさほど難しくなさそうです。Flutterを覚えればマルチプラットフォームでスマートフォンアプリが開発できるようになりますので覚えてみてはいかがでしょう。

中津川 篤司

中津川 篤司

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