CodeZine(コードジン)

特集ページ一覧

Worklightを使用する:
第2回 構造化モジュールを開発してIBM Worklightの暗号化オフライン・キャッシュ機能を使用する

モバイル・アプリケーションを構造、機能、セキュリティーの層で構成する

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2012/10/29 14:00

目次

Vaultモジュール

 TD.Vaultモジュールは、Worklightの暗号化オフライン・キャッシュ(Encrypted Offline Cache:EOC)機能のラッパーです。EOCはローカル・ストレージ上にHTML5で作成され、cookieを使用しないで永続データを保管する方法となります。EOCには、ストレージをオープンおよびクローズするためのメソッド、そしてオープンされたストレージで値の読み取りおよび書き込みを行うためのメソッドが用意されています。EOCの背後にあるセキュリティーの詳細についてはこの記事では説明しませんが、要点を言えば、EOCはユーザー・パスワードを使用してデータを暗号化します。したがって、この特定のモジュールに関連するHTMLコードは、以下の要素が含まれるページ(図1の最初のパネル)となります。

  • ロゴまたはアプリケーション名を表示するヘッダー・イメージ
  • パスコードの入力フィールド (id=’passcode’)
  • パスコードを送信するためのボタン (id=’send_passcode’)
リスト 9. パスコード・ページのHTML
<!-------------------------- PASSCODE PAGE  -------------------------->
<div data-role="page">

<img class="centerimg" src="images/logonobg.png"/>

<div data-role="content">

<div class="center" id="invalid_passcode"></div>

<ul data-role="listview" data-inset="true">
<li data-role="fieldcontain">
<label for="passcode">Enter Passcode:</label> 
<input type="text" name="passcode" id="passcode" value="" placeholder="Your passcode" />
</li>
</ul>

<a id="send_passcode" href="#" data-role="button" data-theme="a">Start</a>
</div>
<!-- /content -->

</div>
<!-- /page -->

 JavaScriptコードでは、まず、グローバル変数を自動実行関数に渡します。この例で渡すグローバル変数は、jQuery$として再定義) とWL(WLとして再定義したWorklightの名前空間)です。次に、依存関係にローカル変数を割り当てることによって、依存関係を「キャッシュ」します。これにより、(WL名前空間をパラメーターとしてモジュールに渡すことなく)簡単にwl.EncryptedCache.openを呼び出して、eocという名前のローカル変数にwl.EncryptedCacheをキャッシュできるようになります。続いて、ユーザーが入力したパスフレーズをKEYというプライベート変数に格納し、パスコード・ボタン、パスコード・フィールド、そしてパスコードが無効な場合にエラー・メッセージを表示するdivに対応するDOM呼び出しを保存します(リスト10を参照)。

リスト10.TD.Vaultモジュール、依存関係、およびプライベート変数の定義
TD.namespace('TD.Vault');
TD.Vault = (function ($, wl) { 
//dependencies
var eoc = wl.EncryptedCache,
log = wl.Logger,
list_obj = TD.List,
CONST = TD.Constant,

//private variables
KEY = "",
send_passcode_btn = $('#send_passcode'),
passcode_fld = $('#passcode'),
invalid_passcode_div = $('#invalid_passcode'),
最後の演習

 Worklightの資料を調べて、onErrorHandler()コールバック関数から返されたステータス・コードに基づくエラー固有の処理を実装してください。

 続いて、いくつかのプライベート関数を定義します。最初の_error()は、エラー・コールバックを受け取った場合にログに記録するだけの関数です。_setData()および_getData()メソッドは、それぞれ暗号化および復号するデータの取得方法と設定方法を指定します(リスト11を参照)。

リスト11. _error()、_setData()、および _getData() 関数の定義
//private functions
_error = function () {
log.debug("error");
},

_setData = function (new_list) {
if (new_list) {
list_obj.set(new_list);
list_obj.refresh();
} 
},

_getData = function () {
return list_obj.get();
},

 イベント定義では、TD.Listと同様にsend_passcode_btnをクリック・イベントにアタッチし、ユーザーがアプリケーションの開始時に入力したパスコードの長さが1文字以上である場合、そのパスコードをプライベート変数KEYに割り当てます(リスト12を参照)。

リスト12. パスコード送信ボタンをイベントへアタッチする
send_passcode_btn.on('click', function () {

var passcode = passcode_fld.val();

if (passcode.length > 0) {
KEY = passcode;

_decrypt();

$.mobile.changePage("#main", { transition: CONST.DEFAULT_TRANSITION });

} else {
passcode_fld.val('');
invalid_passcode_div.text('Invalid Passcode.');
}

});

 次に、EOCの中身を復号するためにプライベート関数_decrypt()を呼び出します。この関数では、暗号化されたキャッシュをオープンした後に復号することになることを示す定数 (CONST.DECRYPT) を引数に指定して_open()を呼び出します。_open() 関数はeoc-openイベントをトリガーして該当するアクション(復号) を送信し、その結果として_read()が呼び出されます。_read()では、ユーザーが提供したキーを使用して、暗号化されたキャッシュの読み取りが試行されます。この時点で_setData()を呼び出し、parseJSON() によって構文解析されてJavaScript配列に戻されたデータを引数として渡します(この配列には、すべてのインデックスに対して1つの項目を表すキーと値のペアが含まれています)。キャッシュから何かが返された場合には、Listモジュールのset()を呼び出して、返されたリストを新しいリストとして設定します。そして最後に、TD.ListのPublic APIのrefresh()を呼び出して、HTMLのリスト要素を最新の表示に更新します。

リスト 13. _close()、_write()、_read()、_encrypt()、および _decrypt() 関数と eoc-open イベント・リスナー
_close = function () {
var onCompleteHandler = function () { 
$.publish('eoc-closed'); 
};

//function(onCompleteHandler, onErrorHandler)
eoc.close(onCompleteHandler, _error);
},

_write = function () {
var data = JSON.stringify(_getData());

//function(key, data, onCompleteHandler, onErrorHandler)
eoc.write(CONST.TODO_ITEMS_KEY, data, _close, _error); 
},

_read = function () {
var onCompleteHandler = function (data) {
_setData($.parseJSON(data)); 
_close(); 
};

//function(key, onCompleteHandler, onErrorHandler)
eoc.read(CONST.TODO_ITEMS_KEY, onCompleteHandler, _error);
},

_encrypt = function () {
_open(CONST.ENCRYPT);
},

_decrypt = function () {
_open(CONST.DECRYPT);
};

$.subscribe("eoc-open", function (e, action) {
if (action) { // == CONST.ENCRYPT
_write();
} else { // == CONST.DECRYPT
_read();
}
});

 暗号化もほとんど同じステップに従います。異なる点は、キャッシュをオープンした後のアクションが _read()ではなく_write()の呼び出しであることです。その後_getData()を実行して最新のリストを取得し、それをJSON.stringify()で文字列に変換した上で、そのストリングをキャッシュに格納します。暗号化および復号が完了するごとに、キャッシュをクローズしてください。

 図4と図5に、完成したアプリケーションがiPhoneシミュレーター上で実行されている様子を示します。

図4.完成したアプリケーションがiPhoneシミュレーター上で実行されている様子 (パスコードのページ)
図4.完成したアプリケーションがiPhoneシミュレーター上で実行されている様子 (パスコードのページ)
図5.完成したアプリケーションがiPhoneシミュレーター上で実行されている様子 (メイン・ページ)
図5.完成したアプリケーションがiPhoneシミュレーター上で実行されている様子 (メイン・ページ)

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:モバイル・エンタープライズ・アプリケーションの統合プラットフォーム「IBM Worklight」

著者プロフィール

  • Carlos Andreu(Carlos Andreu)

    Carlos Andreu は、IBM Software Group のソフトウェア開発者で、現在はハイブリッド・アプリケーション、Android アプリケーション、iOS アプリケーションを構築するためのフレームワークの作成に取り組んでいます。彼は、最新のトレンドと技術関連のブログを追ったり、読書...

  • Jeremy Nortey(Jeremy Nortey)

    Jeremy Nortey は、Software Group に所属する IBM Mobile Foundation のソフトウェア開発者として、モバイル・ソリューションのソフトウェアおよび品質保証を開発しています。iOS を専門としており、余暇は iPhone のネイティブ・アプリケーションの作成...

  • Raj Balasubramanian(Raj Balasubramanian)

    Raj Balasubramanian は、IBM Mobile Foundation に取り組んでいる IBM Software Group の製品アーキテクトです。彼は、IBM Worklight と IBM Mobile Foundation でのクライアントとサービスの対話を指揮しています。...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5