
Rilascio su GitHub un’app sotto la licenza Open Source MIT; l’idea sulla quale si basa è quella di connettere lo smartphone ad un sito web WordPress attraverso l’accesso con un utente WordPress, e scaricare alcune informazioni.
L’app è assolutamente inutile, ma getta la base e una struttura entro la quale sviluppare funzionalità aggiuntive, come il recupero degli ordini effettuati in WooCommerce dall’utente loggato, gli articoli scritti da lui o altro.
Si, esiste una libreria (https://pub.dev/packages/flutter_wordpress) e un plugin per effettuare questo collegamento fra Flutter e WordPress. Perchè allora non utilizzo questo sistema?
Il primo motivo è che due plugin required per far funzionare questa cosa, sono abbastanza vecchi, e non so quanto sia il caso di utilizzare plugin vecchi quando si tratta di lavorare con autenticazioni e accessi. Il secondo motivo è che la libreria permette di fare molte cose, fra cui il reset della password dell’utente loggato, o l’interazione con i commenti, molte funzioni che a me non servono. Terzo motivo, il più importante, è che utilizzo questo progetto per creare una base da riutilizzare in altri progetti.
Motivo bonus: fare un progetto da zero è utile per scavare nella struttura di un’app e imparare di più.
La mettiamo. Per quanto in questo caso non sia considerabile un vero e proprio livello di autenticazione, la possibilità di incapsulare i webservice all’interno di una coppia nome utente e password (anche se sono uguali per tutte le installazioni dell’app) è comunque una cosa buona da fare; quantomeno, prima di iniziare anche solo a pensare di cercare una vulnerabilità nei nostri WS, qualcuno dovrà prendersi la briga di decompilare l’app per avere l’URL e le credenziali di base.
Attenzione, perchè non è mai sicuro inserire un URL o delle credenziali nel codice, anche quando viene compilato, ma in questo caso avremo comunque un’accortezza in più; non può bastare, ma è meglio se c’è.
In ogni caso, dal pannello di amministrazione del plugin installato in WordPress, sarà semplice abilitare e disabilitare questa possibilità. Spoiler: nella prima versione non sarà disponibile.
I componenti principali sono due:
Sul sito web installiamo il plugin che crea il punto di contatto con l’app; il primo contatto sarà l’accesso con le credenziali di un qualunque utente WordPress, poi sarà necessario creare un token che identifica l’utente in quello specifico accesso e inviarlo all’app, che lo utilizzerà in tutte le successive richieste (questa parte è spiegata meglio nel paragrafo che dettaglia il plugin).
Stiamo utilizzando i componenti di WP per creare API REST personalizzate, quindi utilizzeremo ‘rest_api_init’ per registrare la Route.
add_action('rest_api_init', 'fncRemoteLogin');
function fncRemoteLogin() {
if(get_option('remote-login-vojocheruh') !== '' && get_option('login-lutanithet') !== ''){
register_rest_route(get_option('remote-login-vojocheruh'), get_option('login-lutanithet'), array(
'methods' => 'POST',
'callback' => 'fnc_restAPIUserLogin',
));
}
[..]
}
Non riporto tutto il codice all’interno di questo articolo (è presente su Github qui), ma solo le parti che ritengo più importanti: qui andiamo a prendere Namespace e Route che abbiamo impostato nel Pannello di amministrazione, e le registriamo.
La funzione di callback è fnc_restAPIUserLogin() che verifica la coppia username/password passata dall’app Flutter e, se è corretta, imposta un “authentication token” che identifica l’utente loggato; il token viene restituito all’app insieme allo stato (loggato o non loggato) ed eventualmente allo user_id.
L’app Flutter avrà ora l’authenticationToken che potrà inviare ad ogni richiesta; ad esempio, quando richiama getUserPost() presente in UserPosts.dart, passa proprio il parametro authenticationToken con metodo post al webservice /fetch-user-personal-posts-lutanithet il quale comporrà la risposta e la invierà all’app.
E’ una pagina nel /wp-admin per configurare alcune impostazioni utili per il plugin; nella prima versione ci sono pochi campi ma crescendo è che saranno presenti gli strumenti di amministrazione.
Tutto è partito da questo articolo https://flutter.dev/docs/cookbook/networking/send-data che stavo studiando per capire qualcosa in più riguardo ai meccanismi con i quali un’app Flutter può interagire con un web server; la buona notizia è che utilizza http come formato di scambio, quindi il tutto è abbastanza simile ad una richiesta http effettuata in javascript con XMLHttpRequest() o con il metodo $.post() di jQuery .
Nell’articolo veniva spiegato come inviare richieste http con metodo “post”, e mi è sembrato sensato iniziare da qui per sviluppare il meccanismo di login e scambio di informazioni della mia app Flutter.
Anche quest’altra risorsa è stata interessante, perchè ripete in maniera più fredda, più da reference, i metodi base di connessione https://medium.com/swlh/how-to-make-http-requests-in-flutter-d12e98ee1cef e perchè fa riferimento anche alla basic authentication che ho intenzione di utilizzare nel progetto.
In main.dart vengono mostrati i campi Email/Passowrd per effettuare l’accesso; una volta ricevuta una risposta positiva con l’authenticationToken, mostriamo il messaggio “Login successful” e due bottoni:
Il primo utilizza Userposts() per chiamare il webservice e visualizzare i titoli dei post scritti dall’utente loggato, mentre il secondo utilizza LatestPosts(); entrambe le classi sono sostanzialmente identiche, ne ho create due soltanto per tenerle separate e modificarle più facilmente in futuro e realizzare funzionalità più interessanti come il download della lista degli ordini WooCommerce, o dei contenuti Premium visibili solo per utenti con determinate caratteristiche. In realtà LatestPosts() utilizza lo stesso getUserPost() di UserPosts(), una piccola licenza poetica per risparmiare tempo.
Le cose interessanti che accadono nell’app possono essere elencate così:
Le dipendenza da aggiungere nel file pubspec.yaml sono questa https://pub.dev/packages/http e questa https://pub.dev/packages/flutter_html e vanno inserite sotto il solito “cupertino_icons: ^1.0.1”.
http: ^0.12.2
flutter_html: ^1.1.1
L’app è appena all’inizio, ma offre queste funzioni base che ritengo utili; poche righe di codice per non perdere ciò che ho imparato a Dicembre 2020, mentre l’obiettivo è farla crescere e utilizzarla nel 2021.