Azure Mobile Apps 向け Apache Cordova プラグインの使用方法

このガイドでは、最新の Azure Mobile Apps 向け Apache Cordova プラグインを使用して一般的なシナリオを実行する方法について説明します。 Azure Mobile Apps を初めて使用する場合は、まず、「 Apache Cordova アプリの作成 」を参照して、バックエンドの作成、テーブルの作成、構築済みの Apache Cordova プロジェクトのダウンロードを行ってください。 このガイドでは、クライアント側の Apache Cordova プラグインに重点を置いています。

サポートされているプラットフォーム

この SDK は、iOS、Android、Windows の各デバイスで Apache Cordova v6.0.0 以降をサポートしています。 プラットフォームのサポートは次のとおりです。

  • Android API 19+
  • iOS バージョン 8.0 以降

警告

この記事は、廃止された v4.2.0 ライブラリ バージョンについて説明したものです。 このライブラリに対しては、セキュリティの問題に関する更新プログラムも含め、今後の更新は行われません。 継続的なサポートのために、.NET MAUI などの .NET クライアントへの移行を検討してください。

セットアップと前提条件

このガイドでは、バックエンドとテーブルを作成済みであることを前提としています。 例では、クイック スタートの TodoItem テーブルを使用します。 プロジェクトに Azure Mobile Apps プラグインを追加するには、次のコマンドを使用します。

cordova plugin add cordova-plugin-ms-azure-mobile-apps

Apache Cordova アプリを初めて作成する場合は、 こちらのドキュメントを参照してください。

Ionic v2 アプリのセットアップ

Ionic v2 プロジェクトを適切に構成するには、最初に基本的なアプリを作成してから、Cordova プラグインを追加します。

ionic start projectName --v2
cd projectName
ionic plugin add cordova-plugin-ms-azure-mobile-apps

次の行を app.component.ts に追加してクライアント オブジェクトを作成します。

declare var WindowsAzure: any;
var client = new WindowsAzure.MobileServiceClient("https://yoursite.azurewebsites.net");

これで、ブラウザーでプロジェクトを構築して実行できます。

ionic platform add browser
ionic run browser

Azure Mobile Apps の Cordova プラグインは、Ionic v1 アプリと Ionic v2 アプリの両方をサポートしています。 Ionic v2 アプリの場合のみ、追加で WindowsAzure オブジェクトの宣言が必要です。

クライアント接続の作成

WindowsAzure.MobileServiceClient オブジェクトを作成して、クライアント接続を作成します。 appUrl を Mobile App の URL に置き換えます。

var client = WindowsAzure.MobileServiceClient(appUrl);

テーブルに関する作業

データへのアクセスやデータの更新を行うには、バックエンド テーブルへの参照を作成します。 tableName を実際のテーブルの名前に置き換えます。

var table = client.getTable(tableName);

テーブル参照を作成したら、テーブルで次の操作を行うことができます。

テーブル参照でクエリを実行する

テーブル参照を作成したら、それを使用してサーバー上のデータのクエリを実行できます。 クエリは "LINQ のような" 言語で作成します。 テーブルからすべてのデータを返すには、次のコードを使用します。

/**
 * Process the results that are received by a call to table.read()
 *
 * @param {Object} results the results as a pseudo-array
 * @param {int} results.length the length of the results array
 * @param {Object} results[] the individual results
 */
function success(results) {
   var numItemsRead = results.length;

   for (var i = 0 ; i < results.length ; i++) {
       var row = results[i];
       // Each row is an object - the properties are the columns
   }
}

function failure(error) {
    throw new Error('Error loading data: ', error);
}

table
    .read()
    .then(success, failure);

success 関数は results を指定して呼び出します。 success 関数で for (var i in results) は使用しないでください。これを指定すると、他のクエリ関数 (.includeTotalCount() など) を使用した場合に、その結果に含まれる情報が反復処理されるためです。

クエリ構文の詳細については、クエリ オブジェクトのドキュメントを参照してください。

サーバー上のデータのフィルター処理

テーブル参照に対して where 句を使用できます。

table
    .where({ userId: user.userId, complete: false })
    .read()
    .then(success, failure);

オブジェクトをフィルター処理する関数を使用することもできます。 この場合は、フィルター処理対象の現在のオブジェクトに this 変数を割り当てます。 次のコードは、機能的には前の例と同じです。

function filterByUserId(currentUserId) {
    return this.userId === currentUserId && this.complete === false;
}

table
    .where(filterByUserId, user.userId)
    .read()
    .then(success, failure);

データのページング

take() メソッドと skip() メソッドを使用します。 たとえば、テーブルを 100 行のレコードに分割する場合:

var totalCount = 0, pages = 0;

// Step 1 - get the total number of records
table.includeTotalCount().take(0).read(function (results) {
    totalCount = results.totalCount;
    pages = Math.floor(totalCount/100) + 1;
    loadPage(0);
}, failure);

function loadPage(pageNum) {
    let skip = pageNum * 100;
    table.skip(skip).take(100).read(function (results) {
        for (var i = 0 ; i < results.length ; i++) {
            var row = results[i];
            // Process each row
        }
    }
}

.includeTotalCount() メソッドを使用して、results オブジェクトに totalCount フィールドを追加します。 totalCount フィールドには、ページングを使用しない場合に返されるレコード数の合計が入力されます。

pages 変数といくつかの UI ボタンを使用して、ページ リストを指定できます。loadPage() を使用すると、ページごとに新しいレコードを読み込むことができます。 既に読み込まれているレコードへのアクセス時間を短縮するには、キャッシュを実装します。

並べ替えられたデータを返す

.orderBy() クエリ メソッドまたは .orderByDescending() クエリ メソッドを使用します。

table
    .orderBy('name')
    .read()
    .then(success, failure);

クエリ オブジェクトの詳細については、[クエリ オブジェクトのドキュメント]を参照してください。

データの挿入

適切な日付を指定して JavaScript オブジェクトを作成し、table.insert() を非同期に呼び出します。

var newItem = {
    name: 'My Name',
    signupDate: new Date()
};

table
    .insert(newItem)
    .done(function (insertedItem) {
        var id = insertedItem.id;
    }, failure);

挿入に成功すると、挿入された項目が、同期操作で必要な追加のフィールドで返されます。 以降の更新に対しては、この情報を保持する独自のキャッシュを更新します。

Azure Mobile Apps Node.js サーバー SDK では、開発用に動的なスキーマをサポートしています。 動的スキーマでは、挿入操作または更新操作で列を指定するだけで、テーブルに列を追加できます。 実稼働環境にアプリケーションを移行する前に、動的スキーマを無効にしておくことをお勧めします。

データの変更

.insert() メソッドの場合と同様に、update オブジェクトを作成して .update() を呼び出す必要があります。 update オブジェクトには更新するレコードの ID を含める必要があります。この ID は、レコードの読み取り時または .insert() の呼び出し時に取得されます。

var updateItem = {
    id: '7163bc7a-70b2-4dde-98e9-8818969611bd',
    name: 'My New Name'
};

table
    .update(updateItem)
    .done(function (updatedItem) {
        // You can now update your cached copy
    }, failure);

データの削除

レコードを削除するには、.del() メソッドを呼び出します。 オブジェクト参照に ID を渡します。

table
    .del({ id: '7163bc7a-70b2-4dde-98e9-8818969611bd' })
    .done(function () {
        // Record is now deleted - update your cache
    }, failure);

ユーザーの認証

Azure App Service は、Facebook、Google、Microsoft アカウント、Twitter などのさまざまな外部 ID プロバイダーを使用したアプリケーション ユーザーの認証と承認をサポートします。 テーブルのアクセス許可を設定することにより、特定の操作へのアクセスを認証されたユーザーのみに制限できます。 さらに、認証されたユーザーの ID を使用することにより、サーバー スクリプトで承認ルールを実装することもできます。 詳細については、チュートリアル「 モバイル サービスでの認証の使用 」を参照してください。

Apache Cordova アプリで認証を使用する場合は、次の Cordova プラグインが使用できる状態になければなりません。

Note

iOS および Android での最新のセキュリティ変更により、サーバーフロー認証を使用できなくなる場合があります。 このような場合は、クライアントフローを使用する必要があります。

サーバー フローとクライアント フローの 2 つの認証フローがサポートされます。 サーバー フローには、プロバイダーの Web 認証のインターフェイスを利用する、最も簡単な認証方法が用意されています。 クライアント フローでは、プロバイダー固有およびデバイス固有の SDK を利用することから、シングル サインオンなどのデバイス固有の機能との統合がさらに進みます。

プロバイダーでの認証 (サーバー フロー)

Mobile Apps によってアプリの認証プロセスを管理するには、アプリを ID プロバイダーに登録する必要があります。 その後、Azure App Service 内で、プロバイダーから提供されたアプリケーション ID とシークレットを構成する必要があります。 詳細については、チュートリアル「 アプリへの認証の追加」を参照してください。

ID プロバイダーを登録したら、プロバイダーの名前を指定して .login() メソッドを呼び出します。 たとえば、Facebook にサインインするには、次のコードを使用します。

client.login("facebook").done(function (results) {
     alert("You are now signed in as: " + results.userId);
}, function (err) {
     alert("Error: " + err);
});

プロバイダーの名前として有効な値は、"aad"、"facebook"、"google"、"microsoftaccount"、"twitter" です。

Note

セキュリティ上の問題により、一部の認証プロバイダーはサーバーフローで動作しない場合があります。 このような場合は、クライアントフローの方法を使用する必要があります。

この場合は、Azure App Service が OAuth 2.0 認証フローを管理します。 選択されたプロバイダーのサインイン ページを表示し、ID プロバイダーでのサインインが成功した後で App Service 認証トークンを生成します。 login 関数は、完了すると、userId フィールドのユーザー ID と authenticationToken フィールドの App Service 認証トークンの両方を公開する JSON オブジェクトを返します。 このトークンをキャッシュし、有効期限が切れるまで再利用できます。

プロバイダーでの認証 (クライアント フロー)

アプリケーションは個別に ID プロバイダーにアクセスして、返されたトークンを認証のために App Service に提供することもできます。 このクライアント フローでは、ユーザーにシングル サインイン エクスペリエンスを提供したり、ID プロバイダーから追加のユーザー データを取得したりすることができます。

ソーシャル認証の基本的な例

この例では、認証用の Facebook クライアント SDK を使用します。

client.login("facebook", {"access_token": token})
.done(function (results) {
     alert("You are now signed in as: " + results.userId);
}, function (err) {
     alert("Error: " + err);
});

この例では、それぞれのプロバイダー SDK で提供されるトークンが変数 token に格納されるとします。 各プロバイダーで必要な詳細は多少異なります。 ペイロードの正確な形式を判断するには、Azure App Service の認証と承認に関するドキュメントを参照してください。

認証されたユーザーに関する情報の取得

認証情報は、HTTP/REST ライブラリによる HTTP 呼び出しを使用して /.auth/me エンドポイントから取得できます。 X-ZUMO-AUTH ヘッダーを認証トークンに設定していることを確認してください。 認証トークンは client.currentUser.mobileServiceAuthenticationTokenに格納されています。 たとえば、次のフェッチ API を使用します。

var url = client.applicationUrl + '/.auth/me';
var headers = new Headers();
headers.append('X-ZUMO-AUTH', client.currentUser.mobileServiceAuthenticationToken);
fetch(url, { headers: headers })
    .then(function (data) {
        return data.json()
    }).then(function (user) {
        // The user object contains the claims for the authenticated user
    });

フェッチは npm パッケージとして、または CDNJS からのブラウザーのダウンロードに使用できます。 データは JSON オブジェクトとして取得されます。

外部リダイレクト URL 用に Mobile App Service を構成する方法

いくつかの種類の Apache Cordova アプリケーションでは、ループバック機能を使用して OAuth UI フローを処理します。 既定では認証サービスで認識されるのはサービスの利用方法だけであるため、localhost 上の OAuth UI フローによって問題が発生します。 問題のある OAuth UI フローの例は次のとおりです。

  • Ripple エミュレーター
  • Ionic による Live Reload
  • モバイル バックエンドのローカルでの実行
  • 認証を提供するものとは別の Azure App Service でのモバイル バックエンドの実行

ローカル設定を構成に追加するには、以下の手順に従います。

  1. Azure ポータル

  2. [すべてのリソース] または [App Services] を選択し、モバイル アプリの名前をクリックします。

  3. [ツール]

  4. [監視] メニューの [リソース エクスプローラー] をクリックし、[実行] をクリックします。 新しいウィンドウまたはタブが開きます。

  5. 左側のナビゲーションで、サイトの [config] ノード、[authsettings] ノードの順に展開します。

  6. [編集]

  7. "allowedExternalRedirectUrls" 要素を探します。 この要素は、null または値の配列に設定できます。 値を次の値に変更します。

    "allowedExternalRedirectUrls": [
        "http://localhost:3000",
        "https://localhost:3000"
    ],
    

    URL をご使用のサービスの URL に置き換えます。 例には、http://localhost:3000 (Node.js サンプル サービス用)、または http://localhost:4400 (Ripple サービス用) が含まれています。 ただし、これらの URL は例にすぎません。例に示されているサービスの状況など、状況が異なる場合があります。

  8. 画面の右上隅にある [読み取り/書き込み] ボタンをクリックします。

  9. 緑色の [PUT] ボタンをクリックします。

この時点で設定が保存されます。 設定の保存が完了するまで、ブラウザー ウィンドウを閉じないでください。 また、App Service の CORS 設定に、これらのループバック URL を追加します。

  1. Azure ポータル
  2. [すべてのリソース] または [App Services] を選択し、モバイル アプリの名前をクリックします。
  3. [設定] ブレードが自動的に開きます。 開かない場合は、 [すべての設定]をクリックします。
  4. API メニューの [CORS] をクリックします。
  5. 表示されたボックスに追加する URL を入力して、Enter キーを押します。
  6. 必要に応じて、さらに URL を入力します。
  7. [保存] をクリックして設定を保存します。

新しい設定が有効になるまで約 10 ~ 15 秒かかります。