Oggi le applicazioni web sono diventate parte integrante della nostra vita, offrendo comode funzionalità che fanno risparmiare tempo e semplificano le attività quotidiane. Ad esempio, la creazione di account su varie piattaforme è una delle azioni più frequenti degli utenti sui siti web.
Gli utenti si aspettano che questo tipo di processo sia rapido e accessibile, sia che si tratti di casa, che di pendolarismo o di relax in spiaggia.
Dietro questa semplicità si nasconde una realtà più complessa. Queste operazioni richiedono spesso l’integrazione con sistemi di terze parti, come i servizi di verifica delle e-mail. Ciò introduce sfide legate alla sicurezza, alla continuità dell’esperienza utente e alla protezione dagli attacchi man-in-the-middle.
Per gli sviluppatori, garantire un’esperienza fluida significa gestire le interazioni tra i sistemi esterni e la sessione web 4D. Ciò comporta il mantenimento del contesto dell’utente, recuperando dati, privilegi e l’esatta fase del suo percorso per completare il processo.
Sembra complicato? Non deve esserlo! Scoprite come costruire applicazioni web robuste che comunicano in modo sicuro ed efficiente con sistemi di terze parti con 4D 20R9.
Spesso, nelle applicazioni web, l’esperienza dell’utente richiede diversi passaggi come:
Quando si gestiscono le scorte di magazzino dei prodotti:
- effettuare una selezione di prodotti
- inviare la selezione a un sistema di registrazione esterno
- tornare all’elenco dei prodotti nell’applicazione
oppure
Quando si crea un account su un sito web:
- inserire l’e-mail + la password per creare l’account
- convalidare l’e-mail cliccando su un link ricevuto in un’e-mail per finalizzare la creazione dell’account
Questi passaggi richiedono di andare avanti e indietro con sistemi di terze parti. Pertanto, una sessione web 4D deve essere identificata in modo univoco sul server per poter essere recuperata in seguito.
LA FUNZIONE createOTP() SULL’OGGETTO SESSIONE
L’identificatore di una sessione Web 4D è il cookie di sessione (“4DSID_AppName“). Lo scambio del valore di questo cookie in rete tra un’applicazione Web 4D e un sistema di terze parti rappresenta una maldestra violazione della sicurezza.
Per evitare ciò, in qualsiasi processo web è possibile generare un codice di accessounico(OTP) grazie alla nuova funzione createOTP() disponibile sull’oggetto Session.
Questo OTP è collegato alla sessione e consente di recuperarlo in una richiesta ricevuta, che non riceve il cookie di sessione.
Questo OTP può essere utilizzato una sola volta e può essere associato a una durata di vita.
esempio
var $token : Text
$token:=Session.createOTP()
Come si recupera una sessione web grazie all’OTP?
La sessione web può essere recuperata in due modi.
il parametro $4DSID in un URL
La sessione web viene recuperata automaticamente se la richiesta ricevuta contiene nel parametro $4DSID un OTP valido corrispondente alla sessione.
esempio
In questo esempio, nella classe di dati Users viene creato un account utente con la funzione create().
Viene ricevuto un oggetto $info con l’email e la password. Viene creato un nuovo utente e alcune informazioni vengono memorizzate nella sessione, in particolare la fase corrente del processo di creazione dell’account utente(attesa dell’e-mail di convalida) e l’ID utente.
Viene generato un OTP corrispondente alla sessione corrente. Infine, viene restituito un URL con questo OTP indicato nel parametro $4DSID.
// In the Users dataclass
Function create($info : Object) : Text
var $user : cs.UsersEntity
var $status : Object
var $token : Text
//A new entity of the Users dataclass is created
$user:=This.new()
$user.fromObject($info)
$status:=$user.save()
Use (Session.storage)
Session.storage.status:=New shared object("step"; "Waiting for validation email"; "email"; $user.email; "ID"; $user.ID)
End use
$token:=Session.createOTP()
return "https://my4DApp/validateEmail?$4DSID="+$token
Successivamente, all’utente viene inviato questo URL come link in un’e-mail. Il prefisso URL /validateEmail è gestito dai gestori di richieste HTTP (file HTTPHandlers.json).
[
{
"class": "RequestHandler",
"method": "validateEmail",
"regexPattern": "/validateEmail",
"verbs": "get"
}
]
Ecco la funzione validateEmail() del singleton RequestHandler.
Function validateEmail() : 4D.OutgoingMessage
var $result:=4D.OutgoingMessage.new()
var $user : cs.UsersEntity
var $status : Object
If (Session.storage.status.step="Waiting for validation email")
$user:=ds.Users.get(Session.storage.status.ID)
$user.validated:=True
$status:=$user.save()
$result.setBody("Congratulations <br>"\
+"Your email "+Session.storage.status.email+" has been validated")
$result.setHeader("Content-Type"; "text/html")
Use (Session.storage.status)
Session.storage.status.step:="Email validated"
End use
Else
// Retrieving the session with the OTP failed
$result.setBody("Validation failed")
End if
return $result
Poiché il parametro $4DSID contiene un OTP valido corrispondente alla sessione originale, l’oggetto Session si riferisce alla sessione che ha creato l’OTP.
Ecco il risultato in un browser:
LA FUNZIONE restore() SULL’OGGETTO SESSIONE
Di solito, quando è coinvolto un sistema di terze parti, si applica un meccanismo di callback. Il principio è:
- inviare una richiesta al sistema di terze parti e passare un URL di callback
- dopo aver elaborato la richiesta, il sistema di terze parti richiama l’URL di callback
A volte, i sistemi di terze parti non consentono agli URL di callback di contenere parametri personalizzati come $4DSID.
Tuttavia, consentono di inviare informazioni sul client(ad esempio, uno stato) e il sistema di terze parti restituisce queste informazioni al chiamante. Questo è un modo per essere richiamati con un OTP di sessione web 4D.
Controllare la documentazione dell’API del sistema di terze parti per trovare il nome del parametro in questione. L’esempio che segue utilizza il parametro state.
Sull’oggetto Session è disponibile la funzione restore(), che consente di recuperare la sessione corrispondente a un determinato OTP.
Nell’esempio seguente, l ‘OTP viene inserito nel parametro riservato state invece di essere aggiunto nell’URL come parametro $4DSID .
esempio
In un’applicazione web 4D, un dipendente del magazzino seleziona i prodotti per fare un inventario e li invia a un sistema esterno per la registrazione. Ecco la funzione sendProducts() chiamata:
exposed Function sendProducts($chosenProducts : cs.ProductsSelection) : Text
var $token; $callBackURL; $callExternalAppURL; $result : Text
var $request : Object
//The chosen products are put in the session
Use (Session.storage)
Session.storage.info:=New shared object("inventoryStatus"; "Calling registring app")
Session.storage.chosenProducts:=$chosenProducts
End use
// $token is C318C81651F84F238EE72C14B46A45C3 (example)
$token:=Session.createOTP()
//Build the callback URL - Put the OTP in the state parameter
$callBackURL:="https://my4DApp/callBack?state="+$token
// Call the external registring system - Put the callback URL in the redirect parameter
$callExternalAppURL:="https://acme.com/callRegistringApp?redirect="+$callBackURL
$requestObj:={method: HTTP POST method}
$request:=4D.HTTPRequest.new($callExternalAppURL; $requestObj).wait()
// The external registring system made the call back. This call back retrieved and updated the Session
// So now the inventoryStatus attribute is up to date
If (Position("Products registered"; Session.storage.info.inventoryStatus)#0)
$result:=Session.storage.info.inventoryStatus
Else
$result:="Registering failed"
End if
return $result
I prodotti scelti vengono inseriti nella sessione e viene generato un OTP.
Viene chiamato il sistema di terze parti. Il parametro redirect indica l’URL di callback. Questo URL contiene il parametro di stato, che è l’OTP della sessione.
Nell’esempio precedente, l’URL del sistema di terze parti è:
https://acme.com/callRegistringApp?redirect=https://my4DApp/callBack?state=C318C81651F84F238EE72C14B46A45C3
Il prefisso URL /callBack è gestito dai gestori di richieste HTTP (file HTTPHandlers.json) nell’applicazione web 4D.
[
{
"class": "RequestHandler",
"method": "handleCallBack",
"regexPattern": "/callBack",
"verbs": "post"
}
]
Ecco la funzione handleCallback() del singleton RequestHandler:
Function handleCallBack($request : 4D.IncomingMessage)
//Get the state parameter in the URL
$otp:=$request.urlQuery.state
//Restore the session thanks to the OTP
$restore:=Session.restore($otp)
//Restoring the session is successful
If ($restore=True)
//Get the body of the request (information sent by the third party system) - It contains "Products registered"
$text:=$request.getText()
//Update the session with the registring result
If ($text#Null)
Use (Session.storage.info)
Session.storage.info.inventoryStatus:=$text
If (Session.storage.chosenProducts#Null)
Session.storage.info.inventoryStatus+=" total price: "+String(Session.storage.chosenProducts.sum("price"))
End if
End use
End if
End if
Informazioni sulla licenza del client 4D che consuma
Solo la sessione originale (che genera l’OTP) consuma una licenza del client 4D. Il ripristino di una sessione (ad esempio con un link e-mail di convalida) non consuma alcuna licenza 4D Client aggiuntiva.
Scaricate l’HDI allegato per eseguire questi esempi dal vivo e consultate la documentazione per saperne di più.