Sinora nel progetto oggetto di questa serie non abbiamo in alcun modo introdotto alcun tipo di sicurezza: chiunque usi la nostra app è in grado di utilizzarne i servizi senza nessun limite o controllo.

Inoltre per sempicità il campo nome utente che correda ogni post è un semplice campo di testo, dove ognuno può metterci il valore che desidera.

Ovviamente per molti utilizzi questa libertà non rappresenta il comportamento voluto: nel nostro caso occorre che almeno il campo nome utente all'atto di inserimento del post sia riempito in modo sensato e con un minimo di sicurezza in modo da comprendere chi-ha-scritto-cosa.

E' arrivato il momento di parlare di autenticazione e autorizzazione ! Prima però occorre introdurre un minimo di teoria.

Iniziamo con qualche definizione.

L’autenticazione è il processo che permette di identificare l’utilizzatore del software in modo sicuro: cioè identificare in modo certo un nome utente.

Questo processo nel passato veniva svolto escluivamente tramite l’ausilio di una userid e una password: il concetto che sottende questo tipo di autenticazione è che solo chi conosce la relativa password è in grado di sostenere di essere realmente l’utente specificato.

Ho già parlato nella quinta parte di questa serie della gestione della concorrenza, introducendo la teoria che sottende l'optimistc concorrency così come implementato dall'SDK Azure Mobile, ed esposto aluni codici pratici per gestire la problematica .

In questo momento, però, si sta parlando dell'offline-sync: in tale contesto vedremo che le cose, seppur simili a quanto visto in precedenza, sono giocoforza un pò più complicate.

Inziamo con il dire che per rilevare le modifiche concorrenti la tecnica dall'SDK è sempre la stessa: utilizzo della colonna version (...squadra vincente non si cambia, no ?).

Però nell'online-sync ogni singolo salvataggio viene sottoposto al backend, e quindi l'eventuale gestione della modifica concorrente avviene sul singolo record oggetto del salvataggio.

Nell'offline-sync, invece, a fronte di un singolo push (implicit o meno) si possono sottoporre al backend un numero imprecisato di record modificati, che magari insistono su più tabelle.

Per questo motivo in questo in questo caso potrebbe essere necessario gestire le modifiche concorrenti di più di un record oggetto dell'operazione di push.

Rammento che il push nell'offline-sync sottopone tutte le modifiche avvenute sul database locale SqLite al backend per la loro persistenza sulla base dati remota con lo stesso ordine con cui queste sono avvenute, e richiamando i vari metodi dei controller coinvolti, semplicemente invocando il metodo PushAsync dell'oggetto SyncContext.

Per questo motivo nel caso dell'offline-sync l'SDK Azure Mobile Client mette a disposizione una gestione più articolata della concorrenza, anche se i principi ispiratori sono assolutamente analoghi a quanto già visto.

Aggiungo anche che lavorare con offline-sync sicuramente introduce maggiori probabilità di avere modifiche concorrenti, e un'applicatvo reale dovrebbe poter gestire questa parte in modo preciso e dettagliato sopratutto quando sono coinvolte più tabelle che magari hanno relazioni semantiche tra esse.

Nel seguito un primo esempio di codice utilizzato per gestire i problemi relativi alla concorrenza.

Giunti a questo punto abbiamo la nostra app che serve per condividere i posti dove si mangia la vera focaccia genovese, dotata di gestioe della concorrenza e offline-sync.

Ora però occorre introdurre la possibilità di cancellare in modo corretto un item: più in dettaglio occorre introdurre un meccanismo che permetta a un record, scaricato in modalità offline da più dispositivi e successivamente cancellato da uno di questi che ne ha la facoltà, venga successivamente cancellato anche dal database locale degli altri client mobile coinvolti.

Al momento il meccanismo è questo: un record cancellato da un client viene rimosso al primo push anche sul database Sql Server: sincronizzazioni successive di altri dispositivi non vedranno alcuna traccia di tale record, e quindi lo lasceranno intonso nella propria base dati locale SqLite.

Occorre osservare che questa situazione secondo la logica esposta è assolutamente normale poichè si sta usando la sincronizzazione incrementale, e il record cancellato non viene riproposto in alcun modo nella fase di push incrementale (anzi proprio non esiste più..).

Quindi in una situazione come questa tutti gli altri dispositivi, all'infuori di quello che lo ha realmente cancellato, continueranno ad avere lo stesso record ben presente nella base dati.

Solo una sincronizzazione pull totale e non incremenatel (per esempio reinstallazione totale dell’applicativo, che cancella la base dati locale) non farà più comparire corretamente detto record.

Questa situazione in alcuni casi può essere perfettamente compatibile con le aspettative: in altre assolutamente no.

Gli esempi visti sinora funzionano correttamente: l'unica condizione è che il dispositivo in fase di salvataggio e lettura dei dati abbia a disposizione connettività per potersi connettere al backend.

Inoltre i dati vengono scaricati vengono mantenuti nlla memoria volatile del client: chiudere l'applicativo significa perdere irrimediabilmente le informazioni e la necessità di connettività per riscaricarli.

Inoltre ogni modifica eseguita verrà sottoposta subito al backend per la persistenza su Sql Server.

Detto in altri termini non esiste alcuna persistenza locale, ma solo quella remota su Sql Server, che avviene con l'ausilio del backend ospitato sui servizi Mobile App di Azure.

Per avere la possibilità di salvare il record anche senza connettività, nonchè poter fare delle query sugli stessi dati, occorre introdurre sua maestà l'offline-sync.

Con questo strumento è possibile interagire con un database locale, SqLite, che sarà sincronizzato con il database Sql Server sempre usando i servizi Mobile App Service. Quind tutte le interrogazioni e modifiche avranno come destinatario questo il database locale, e non si avrà necessità di alcuna connessione.

Solo in fase di sincronizzazione del database locale con quello remoto si avrà necessità di connettività per far interagire il client  con i servizi di backend.

Anche per introdurre l'offlie-sync è necessario agire solo sul codice della app (cioè lato client), e la modiifca più notevole è che questa volta si userà l'oggetto che implementa l’interfaccia IMobileServiceSyncTable (prima si usava IMobileServiceTable).