Come usare la libreria client Apache Cordova per App per dispositivi mobili di Azure

Questa guida descrive come eseguire scenari comuni usando il più recente plug-in Apache Cordova per le app per dispositivi mobili di Azure. Se non si ha familiarità con le app per dispositivi mobili di Azure, completare prima di tutto l' esercitazione introduttiva sulle app per dispositivi mobili di Azure per creare un back-end e una tabella e per scaricare un progetto Apache Cordova predefinito. In questa guida si esaminerà il plug-in Apache Cordova.

Piattaforme supportate

Questo SDK supporta Apache Cordova v6.0.0 e versioni successive sui dispositivi iOS, Android e Windows. Il supporto della piattaforma è il seguente:

  • API Android 19-24 (KitKat tramite Nougat).
  • iOS versioni 8.0 e successive.
  • Windows Phone 8.1
  • Piattaforma UWP (Universal Windows Platform).

Installazione e prerequisiti

In questa guida si presuppone che siano stati creati un backend e una tabella. In questa guida si presuppone che la tabella abbia lo stesso schema delle tabelle presenti in tali esercitazioni. Si presuppone anche che il plug-in Apache Cordova sia stato aggiunto al codice. In caso contrario, è possibile aggiungere il plug-in Apache Cordova al progetto nella riga di comando:

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

Per altre informazioni sulla creazione della prima app Apache Cordova, vedere la relativa documentazione.

Configurazione di un'app Ionic v2

Per configurare correttamente un progetto Ionic v2, innanzitutto creare un'applicazione di base e aggiungere il plug-in Cordova:

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

Aggiungere le seguenti righe a app.component.ts per creare l'oggetto client:

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

È ora possibile compilare ed eseguire il progetto nel browser:

ionic platform add browser
ionic run browser

Il plug-in Cordova di App per dispositivi mobili di Azure supporta le app Ionic sia v1 che v2. Solo le app Ionic v2 richiedono la dichiarazione aggiuntiva per l'oggetto WindowsAzure.

Creare una connessione client

Creare una connessione client creando un oggetto WindowsAzure.MobileServiceClient . Sostituire appUrl con l'URL dell'app per dispositivi mobili.

var client = WindowsAzure.MobileServiceClient(appUrl);

Usare le tabelle

Per l'accesso o l'aggiornamento dei dati, creare un riferimento alla tabella di back-end. Sostituire tableName con il nome della tabella

var table = client.getTable(tableName);

Dopo aver creato un riferimento a tabella, saranno disponibili le operazioni seguenti:

Procedura: Eseguire query su un riferimento a tabella

Dopo aver creato un riferimento a tabella, è possibile usarlo per eseguire una query sui dati nel server. Le query vengono eseguite in un linguaggio "simile a LINQ". Per restituire tutti i dati dalla tabella, usare il codice seguente:

/**
 * 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);

La funzione success viene chiamata con l'oggetto results. Non usare for (var i in results) nella funzione success, perché ripete le informazioni incluse nei risultati quando si usano altre funzioni di query, ad esempio .includeTotalCount().

Per altre informazioni sulla sintassi delle query, vedere la [documentazione relativa all'oggetto Query].

Filtro dei dati nel server

È possibile usare una clausola where nel riferimento a tabella:

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

È anche possibile usare una funzione che filtra l'oggetto. In questo caso la variabile this viene assegnata all'oggetto che si sta filtrando. A livello funzionale, il codice seguente è equivalente al precedente:

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

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

Paging dei dati

Usare i metodi take() e skip(). Ad esempio, se si vuole dividere la tabella in record di 100 righe:

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
        }
    }
}

Il metodo .includeTotalCount() viene usato per aggiungere un campo totalCount all'oggetto results. Se non si usa il paging, il campo totalCount viene compilato con il numero totale di record restituiti.

Si potrà quindi usare la variabile pages e alcuni pulsanti dell'interfaccia utente per fornire un elenco di pagine. Usare loadPage() per caricare i nuovi record per ogni pagina. Implementare il caching per velocizzare l'accesso ai record già caricati.

Procedura: Restituire i dati ordinati

Usare i metodi di query .orderBy() o .orderByDescending():

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

Per altre informazioni sull'oggetto delle query, vedere la [documentazione relativa all'oggetto Query].

Procedura: Inserire dati

Creare un oggetto JavaScript con la data appropriata e chiamare table.insert() in modo asincrono:

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

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

Una volta completato l'inserimento, viene restituito l'elemento inserito con i campi aggiuntivi necessari per le operazioni di sincronizzazione. Aggiornare la cache con queste informazioni per gli aggiornamenti successivi.

Node. js Server SDK per le app per dispositivi mobili supporta lo schema dinamico per scopi di sviluppo. Lo Schema dinamico consente di aggiungere colonne alla tabella specificandole in un'operazione di inserimento o aggiornamento. È consigliabile disattivare lo schema dinamico prima di trasferire l'applicazione in produzione.

Procedura: Modificare dati

In modo analogo al metodo .insert(), è consigliabile creare un oggetto Update e quindi chiamare .update(). L'oggetto update deve contenere l'ID del record da aggiornare, che si ottiene durante la lettura del record o quando si chiama .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);

Procedura: Eliminare dati

Per eliminare un record, chiamare il metodo .del(). Passare l'ID in un riferimento all'oggetto:

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

Procedura: Autenticare gli utenti

Il servizio app di Azure supporta l'autenticazione e l'autorizzazione degli utenti di app usando diversi provider di identità esterni, a esempio Facebook, Google, account Microsoft e Twitter. È possibile impostare le autorizzazioni per le tabelle per limitare l'accesso per operazioni specifiche solo agli utenti autenticati. È inoltre possibile utilizzare l'identità degli utenti autenticati per implementare regole di autorizzazione negli script del server. Per ulteriori informazioni, vedere l'esercitazione Introduzione all'autenticazione .

Quando si usa l'autenticazione in un'app Apache Cordova, devono essere disponibili i plug-in Cordova seguenti:

Sono supportati due flussi di autenticazione, ovvero un flusso server e un flusso client. Il flusso server è il processo di autenticazione più semplice, poiché si basa sull'interfaccia di autenticazione Web del provider. Il flusso client assicura una maggiore integrazione con funzionalità specifiche del dispositivo, ad esempio Single-Sign-On, poiché si basa su SDK specifici del provider e del dispositivo.

Procedura: Eseguire l'autenticazione con un provider (flusso server)

Per consentire alle app per dispositivi mobili di gestire il processo di autenticazione nella propria app, è necessario effettuare la registrazione dell'app con il provider di identità. Nel proprio servizio app di Azure è quindi necessario configurare l'ID e il segreto dell'applicazione forniti dal provider. Per altre informazioni, vedere l'esercitazione Aggiungere l'autenticazione all'app di Servizi mobili.

Dopo aver effettuato la registrazione del provider di identità, chiamare il metodo .login() con il nome del provider. Per accedere ad esempio con Facebook, utilizzare il codice seguente:

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

I valori validi per il provider sono "aad", "facebook", "google", "microsoftaccount" e "twitter".

Nota

L'autenticazione di Google attualmente non funziona tramite Flusso server. Per eseguire l'autenticazione con Google, è necessario usare un metodo di flusso client.

In questo caso, il Servizio app di Azure gestisce il flusso di autenticazione OAuth 2.0. Viene visualizzata la pagina di accesso al provider selezionato e viene generato un token di autenticazione del Servizio app dopo aver eseguito correttamente l'accesso con il provider di identità. La funzione login, una volta completata, restituisce un oggetto JSON che espone l'ID utente e il token di autenticazione del servizio app rispettivamente nei campi userId e authenticationToken. È possibile memorizzare questo token nella cache e riutilizzarlo fino alla scadenza.

Procedura: Eseguire l'autenticazione con un provider (flusso client)

L'app può anche contattare il provider di identità in modo indipendente e quindi fornire il token restituito al servizio app per l'autenticazione. Mediante il flusso client è possibile consentire agli utenti di effettuare l'accesso un'unica volta o recuperare dal provider di identità dati utente aggiuntivi.

Esempio di base di autenticazione tramite social network

Questo esempio utilizza il client SDK di Facebook per l'autenticazione:

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

In questo esempio si presuppone che il token fornito dall'SDK del rispettivo provider sia archiviato nella variabile token.

Esempio di account Microsoft

Nell'esempio seguente viene utilizzato Live SDK, che supporta Single-Sign-On per le app di Windows Store tramite un account Microsoft:

WL.login({ scope: "wl.basic"}).then(function (result) {
      client.login(
            "microsoftaccount",
            {"authenticationToken": result.session.authentication_token})
      .done(function(results){
            alert("You are now logged in as: " + results.userId);
      },
      function(error){
            alert("Error: " + err);
      });
});

Questo esempio ottiene un token da Live Connect, che viene fornito al servizio app chiamando la funzione login.

Procedura: Ottenere informazioni relative all'utente autenticato

Le informazioni di autenticazione possono essere recuperate dall'endpoint /.auth/me usando una chiamata HTTP con una libreria AJAX qualsiasi. Assicurarsi di impostare l'intestazione X-ZUMO-AUTH sul token di autenticazione. Il token di autenticazione è memorizzato in client.currentUser.mobileServiceAuthenticationToken. Ad esempio, per usare l'API fetch:

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
    });

L'operazione di recupero è disponibile come pacchetto npm oppure può essere scaricato tramite il browser da CDNJS. È anche possibile usare jQuery o un'altra API AJAX per recuperare le informazioni. I dati saranno ricevuti come oggetto JSON.

Procedura: Configurare il servizio App per dispositivi mobili per URL di reindirizzamento esterni.

Molti tipi di applicazioni Apache Cordova usano una funzionalità di loopback per gestire i flussi dell’interfaccia utente di OAuth. I flussi dell'interfaccia utente di OAuth sull'host locale causa problemi in quanto il servizio di autenticazione sa usare il servizio solo con le impostazioni predefinite. Alcuni esempi di flussi dell'interfaccia utente di OAuth problematici sono:

  • L'emulatore Ripple.
  • Live Reload con Ionic.
  • L'esecuzione del back-end per dispositivi mobili in locale
  • L'esecuzione del back-end per dispositivi mobili in un Servizio app di Azure diverso rispetto a quello che fornisce l'autenticazione.

Per aggiungere le proprie impostazioni locali alla configurazione seguire questa procedura:

  1. Accedere al portale di Azure
  2. Selezionare Tutte le risorse o Servizi app e quindi fare clic sul nome dell'app per dispositivi mobili.
  3. Fare clic su Strumenti
  4. Fare clic su Esplora risorse nel menu OSSERVAZIONE, quindi fare clic su Vai. Si apre una nuova finestra o una nuova scheda.
  5. Espandere i nodi config, authsettings del sito nel riquadro di spostamento a sinistra.
  6. Fare clic su Modifica
  7. Cercare l’elemento "allowedExternalRedirectUrls". Può essere impostato su null o su una matrice di valori. Modificare il valore nel valore seguente:

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

    Sostituire gli URL con quelli del servizio. Ad esempio includere "http://localhost:3000" (per il servizio di esempio Node.js) o "http://localhost:4400" (per il servizio Ripple). Questi URL sono solo esempi e la situazione reale per i servizi dell'esempio potrebbe essere diversa.

  8. Fare clic sul pulsante Lettura/scrittura nell'angolo in alto a destra della schermata.
  9. Fare clic sul pulsante verde PUT .

A questo punto le impostazioni vengono salvate. Non chiudere la finestra del browser finché non è terminato il salvataggio delle impostazioni. Aggiungere gli URL di loopback anche alle impostazioni CORS del servizio app:

  1. Accedere al portale di Azure
  2. Selezionare Tutte le risorse o Servizi app e quindi fare clic sul nome dell'app per dispositivi mobili.
  3. Il pannello Impostazioni si apre automaticamente. In caso contrario fare clic su Tutte le impostazioni.
  4. Fare clic su CORS nel menu API.
  5. Immettere l'URL che si desidera aggiungere nella casella apposita e prema INVIO.
  6. Immettere gli altri URL in base alle esigenze.
  7. Fare clic su Salva per salvare le impostazioni.

Le nuove impostazioni saranno operative in 10-15 secondi.

Procedura: Registrarsi per le notifiche push

Installare phonegap-plugin-push per gestire le notifiche push. Questo plug-in può essere facilmente aggiunto usando il comando cordova plugin add nella riga di comando o tramite il programma di installazione del plug-in Git in Visual Studio. Il codice seguente nell'app Apache Cordova registra il dispositivo per le notifiche push:

var pushOptions = {
    android: {
        senderId: '<from-gcm-console>'
    },
    ios: {
        alert: true,
        badge: true,
        sound: true
    },
    windows: {
    }
};
pushHandler = PushNotification.init(pushOptions);

pushHandler.on('registration', function (data) {
    registrationId = data.registrationId;
    // For cross-platform, you can use the device plugin to determine the device
    // Best is to use device.platform
    var name = 'gcm'; // For android - default
    if (device.platform.toLowerCase() === 'ios')
        name = 'apns';
    if (device.platform.toLowerCase().substring(0, 3) === 'win')
        name = 'wns';
    client.push.register(name, registrationId);
});

pushHandler.on('notification', function (data) {
    // data is an object and is whatever is sent by the PNS - check the format
    // for your particular PNS
});

pushHandler.on('error', function (error) {
    // Handle errors
});

Usare Notification Hubs SDK per inviare notifiche push dal server. Non inviare mai le notifiche push direttamente dai client. Questa operazione può essere usata per attivare un attacco denial-of-service agli Hub di notifica o al servizio PNS. Il servizio PNS potrebbe escludere il traffico come conseguenza di questi attacchi.

Altre informazioni

È possibile trovare informazioni dettagliate sulle API nella documentazione sulle API.