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

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

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

f:id:mbaasdevrel:20190222161221p:plain

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

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

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

必要な引数について

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

変数 名前 説明
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 クライアントキー 管理画面で取得できるクライアントキーです

利用するライブラリについて

署名を生成するために必要なライブラリは下記の通りです。

import hmac
import hashlib
import base64
import json
import urllib.parse
import datetime

生成前の変数について

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

clientKey = '1343d198b510a0315db1c03f3aa0e32418b7a743f8e4b47cbff670601345cf75'
applicationKey = '6145f91061916580c742f806bab67649d10f45920246ff459404c46f00ff3e56'
method = 'GET'
fqdn = 'mbaas.api.nifcloud.com'
path = '/2013-09-01/classes/TestClass'
params = {}
params['SignatureMethod'] = 'HmacSHA256'
params['SignatureVersion'] = '2'
params['X-NCMB-Application-Key'] = applicationKey
params['X-NCMB-Timestamp'] = datetime.datetime(2013, 12, 2, 2, 44, 35, 452000).isoformat()
queries = {}
queries['where'] = {'testKey': 'testValue'}

クエリパラメータをURLエンコーディングする

whereなどのクエリパラメータはURLエンコードする必要があります。dictをJSON文字列にし、それをURLエンコーディングします。

for k, v in queries.items():
    params[k] = urllib.parse.quote(json.dumps(queries[k]).replace('": "', '":"'))

ソートする

パラメータをソートします。さらにHTTPメソッドやFQDNなどを配列にいれ、文字列化する準備をします。

params = sorted(params.items(), key=lambda x: x[0])
arySigs = []
arySigs.append(method)
arySigs.append(fqdn)
arySigs.append(path)
query = []
for k, v in params:
    query.append(f'{k}={v}')
arySigs.append("&".join(query))
signString = "\n".join(arySigs)

署名する

クライアントキーを使って署名を作成します。ハッシュを作成し、それをBASE64エンコードすれば完了です。

print(base64.b64encode(
            hmac.new(
                clientKey.encode('UTF-8'),
                signString.encode('UTF-8'), hashlib.sha256).digest()))

まとめ

Pythonのdatetimeではマイクロセコンドの桁数が6桁となっています。そのためmBaaSのドキュメント通りのパラメータを生成するのは難しいです。アルゴリズムが合っていれば問題なく利用できますので、今回の実装を参考にPythonからもmBaaSを使ってください。

中津川 篤司

中津川 篤司

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