Aujourd’hui, les applications web font partie intégrante de notre vie, offrant des fonctionnalités pratiques qui permettent de gagner du temps et de simplifier les tâches quotidiennes. Par exemple, la création de comptes sur diverses plateformes est l’une des actions les plus fréquentes des utilisateurs sur les sites web.
Ils s’attendent à ce que ce type de processus soit rapide et accessible, que ce soit à la maison, dans les transports ou sur la plage.
Derrière cette simplicité se cache une réalité plus complexe. Ces opérations nécessitent souvent une intégration avec des systèmes tiers, tels que les services de vérification des courriers électroniques. Cela pose des problèmes de sécurité, de continuité de l’expérience utilisateur et de protection contre les attaques de type « man-in-the-middle ».
Pour les développeurs, assurer une expérience fluide signifie gérer les interactions entre les systèmes externes et la session web 4D. Cela implique de maintenir le contexte de l’utilisateur, en récupérant les données, les privilèges et l’étape exacte de son parcours pour terminer le processus.
Cela vous semble compliqué ? Ce n’est pas nécessaire ! Découvrez comment construire des applications web robustes qui communiquent efficacement et en toute sécurité avec des systèmes tiers avec 4D 20R9.
Souvent, sur les applications web, l’expérience de l’utilisateur nécessite plusieurs étapes comme :
Lors de la gestion des stocks de produits dans un entrepôt :
- faire une sélection de produits
- envoyer la sélection à un système d’enregistrement externe
- revenir à la liste des produits dans l’application
ou
Lors de la création d’un compte sur un site web :
- saisir l’email + le mot de passe pour créer le compte
- valider l’email en cliquant sur un lien reçu dans un email pour finaliser la création du compte
Ces étapes nécessitent des allers-retours avec des systèmes tiers. Ainsi, une session web 4D doit être identifiée de manière unique sur le serveur pour être retrouvée ultérieurement.
LA FONCTION createOTP() SUR L’OBJET SESSION
L’identifiant d’une session Web 4D est le cookie de session (« 4DSID_AppName« ). L’échange de cette valeur de cookie sur le réseau entre une application web 4D et un système tiers constitue une violation maladroite de la sécurité.
Pour éviter cela, dans tout processus web, un One-Time-Passcode(OTP) peut être généré grâce à la nouvelle fonction createOTP() disponible sur l’objet Session.
Cet OTP est lié à cette session et permet de le retrouver dans une requête reçue, qui ne reçoit pas le cookie de session.
Cet OTP ne peut être utilisé qu’une seule fois et peut être associé à une durée de vie.
exemple
var $token : Text
$token:=Session.createOTP()
Comment récupérer une session web grâce à l’OTP ?
La session web peut être récupérée de deux manières.
le paramètre $4DSID dans une URL
La session web sera automatiquement récupérée si la requête reçue contient dans le paramètre $4DSID un OTP valide correspondant à la session.
Exemple
Dans cet exemple, un compte utilisateur est créé dans la classe de données Users avec la fonction create().
Un objet $info est reçu avec l’email + le mot de passe. Un nouvel utilisateur est créé et certaines informations sont stockées dans la session, en particulier l’étape actuelle du processus de création du compte utilisateur(Attente du courriel de validation) et l’identifiant de l’utilisateur.
Un OTP correspondant à la session en cours est généré. Enfin, une URL est renvoyée avec cet OTP donné dans le paramètre $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
L’utilisateur reçoit ensuite cette URL sous la forme d’un lien dans un courrier électronique. Le préfixe URL /validateEmail est géré par les gestionnaires de requêtes HTTP (fichier HTTPHandlers.json).
[
{
"class": "RequestHandler",
"method": "validateEmail",
"regexPattern": "/validateEmail",
"verbs": "get"
}
]
Voici la fonction validateEmail() du 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
Comme le paramètre $4DSID contient un OTP valide correspondant à la session d’origine, l’objet Session fait référence à la session qui a créé l’OTP
Voici le résultat dans un navigateur :
LA FONCTION restore() SUR L’OBJET SESSION
En général, un mécanisme de rappel est appliqué lorsqu’un système tiers est impliqué. Le principe est le suivant :
- envoyer une requête au système tiers et lui transmettre une URL de rappel
- après traitement de la requête, le système tiers appelle l’URL de rappel
Parfois, les systèmes tiers n’autorisent pas les URL de rappel à contenir des paramètres personnalisés tels que $4DSID.
Cependant, ils autorisent l’envoi d’informations sur le client(par exemple, un état) et le système tiers renvoie ces informations à l’appelant. Il s’agit d’un moyen d’être rappelé avec un OTP de session web 4D.
Consultez la documentation de l’API du système tiers pour trouver le nom du paramètre en question. L’exemple ci-dessous utilise le paramètre » state ».
Une fonction restore() est disponible sur l’objet Session et permet de récupérer la session correspondant à un OTP donné.
Dans l’exemple ci-dessous, l’OTP est placé dans le paramètre state réservé au lieu d’être ajouté dans l’URL en tant que paramètre $4DSID .
Exemple
Sur une application web 4D, un employé d’entrepôt sélectionne des produits pour en faire un inventaire et les envoie à un système externe pour qu’ils soient enregistrés. Voici la fonction sendProducts() appelée :
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
Les produits sélectionnés sont placés dans la session et un OTP est généré.
Le système tiers est appelé. Le paramètre de redirection indique l’URL de rappel. Cette URL contient le paramètre state, qui est l’OTP de la session.
Dans l’exemple ci-dessus, l’URL du système tiers est :
https://acme.com/callRegistringApp?redirect=https://my4DApp/callBack?state=C318C81651F84F238EE72C14B46A45C3
Le préfixe URL /callBack est géré par les gestionnaires de requêtes HTTP (fichier HTTPHandlers.json) dans l’application web 4D.
[
{
"class": "RequestHandler",
"method": "handleCallBack",
"regexPattern": "/callBack",
"verbs": "post"
}
]
Voici la fonction handleCallback() du 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
À propos de la consommation de licences par le client 4D
Seule la session originale (qui génère l’OTP) consomme une licence 4D Client. La restauration d’une session (par exemple avec un lien de validation par email) ne consomme pas de licence 4D Client supplémentaire.
Téléchargez l’IDH ci-joint pour exécuter ces exemples en direct et consultez la documentation pour en savoir plus.