MySkeletonApp: app Flutter/WP

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.

Ma esiste già!

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ù.

Basic Authentication: la mettiamo o non la mettiamo?

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.

Come funziona il tutto?

I componenti principali sono due:

  1. Sito web con WordPress installato;
  2. App Flutter;

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).

Il plugin per WordPress

Creazione del punto di contatto

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.

Prima richiesta e creazione del token di autenticazione

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.

Richieste successive alla prima

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.

Il pannello di amministrazione

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.

L’app in Flutter

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:

  • Get user’s posts from WP
  • Gest latest posts from WP

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ì:

  1. il main.dart mostra i campi di login se l’utente non è ancora loggato e i bottoni per prendere i post da WP, se invece è loggato;
  2. UserPost() e LatestPost() che fanno le chiamate getUserPost() e, con i FutureBuilder(), mostrano i risultati a video;
  3. le chiamate http in formato json con la parolina “await” che costringe il metodo ad attendere la risposta del server prima di procedere con l’esecuzione dell’app.
  4. WpUserPost() e WpLogin() sono le classi utilizzate per manipolare i dati json restituiti dai webservice.
  5. l’utilizzo di Navigator per mostrare UserPosts() o LatestPosts() passando l’autenticationToken come parametro con “settings: RouteSettings()“.

Dipendenze?

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

Conclusioni

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.


Questo sito web non offre alcun cookie perchè non ho interesse a tracciare le attività di nessun utente attraverso i cookie e quindi non ne ho inseriti.
Il tema e i plugin sono realizzati da me e quindi nessun altro è autorizzato ad inserire cookie su questo sito web.
Se qualcuno dovesse individuare un cookie da qualche parte su questo sito web, non ce l'ho messo io,
ed è pregato di farmelo sapere, così potrò cercare e distruggere il cookie eventualmente individuato.
I software e i pezzi di codice condivisi su questo sito web sono da considerarsi a scopo educativo e senza alcuna garanzia
© 2021