https://d226lax1qjow5r.cloudfront.net/blog/blogposts/add-2fa-to-your-application-with-the-verify-api-and-golang-sdk/go_verify-apis_1200x600.png

Ajoutez 2FA à vos Applications avec l'API Verify et le SDK Golang

Publié le March 16, 2021

Temps de lecture : 17 minutes

Lorsque vous avez travaillé dur pour construire une application web qui offre une réelle valeur à vos utilisateurs, il peut être vraiment décourageant de voir qu'elle est utilisée de manière abusive. Fuite d'informations d'identification, fausses inscriptions... il y a toujours une petite minorité qui cherche à utiliser votre plateforme à des fins malveillantes.

Bien qu'il soit pratiquement impossible d'empêcher cela, vous pouvez dissuader tous les abuseurs, à l'exception des plus convaincus, en mettant en place une authentification à deux facteurs (2FA).

Qu'est-ce que 2FA ?

Le 2FA est une couche de protection supplémentaire qui exige de l'utilisateur qu'il fournisse quelque chose de plus qu'un simple nom d'utilisateur et un mot de passe pour utiliser votre service. Il s'agit généralement d'un accès à un appareil mobile qui peut recevoir un code de sécurité qu'il entre ensuite dans votre application dans le cadre du processus d'inscription ou de connexion. Comme votre numéro de téléphone vous est propre, il est beaucoup plus difficile pour les escrocs d'usurper l'identité d'utilisateurs existants ou de créer plusieurs faux Account.

Un autre bon cas d'utilisation de la 2FA est l'"authentification par paliers". Elle est idéale pour les situations où un utilisateur tente de faire quelque chose dans votre application qui pourrait avoir de mauvaises conséquences si cet utilisateur n'est pas celui qu'il prétend être. Par exemple, si vous avez une application bancaire et que votre utilisateur tente d'ajouter un nouveau bénéficiaire. Dans ce cas, le 2FA permet de s'assurer de la légitimité de l'utilisateur.

L'API Verify de Vonage

L'API Verify API de Vonage de Vonage permet d'implémenter très simplement le 2FA dans vos Applications et c'est ce que nous espérons démontrer dans le billet d'aujourd'hui. Nous allons créer un site simple pour une société fictive appelée Acme Inc, qui exige que les utilisateurs s'inscrivent à l'aide de leur appareil mobile pour ajouter un certain niveau de protection contre l'utilisation frauduleuse.

Et, pour rendre les choses encore plus excitantes, nous allons construire ceci dans notre tout nouveau SDK Go (beta). Cela devrait plaire à tous les Gophers endurcis et peut-être même encourager d'autres personnes à faire leur première expérience du développement Go ? (Alerte au spoiler : je pense que vous allez aimer Go !)

C'est parti ! (Si vous n'avez pas le temps de coder, vous pouvez trouver le code source sur le code source sur GitHub).

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

Créez votre projet

Créez un répertoire pour votre projet et dans ce répertoire, exécutez go mod init. Cela génère un fichier go.mod pour gérer les dépendances.

mkdir go-2fa-example cd go-2fa-example go mod init go-2fa-example

Ensuite, créez un main.go fichier. C'est là que vous écrirez le code de votre application :

touch main.go

Nous allons utiliser les modèles Go pour construire notre site. Créons un répertoire pour eux (tmpl) ainsi que pour les feuilles de style CSS que nous utiliserons pour styliser nos pages (static) :

mkdir tmpl static

Configurer le SDK de Vonage Go

Nous allons utiliser l'API Verify pour demander aux utilisateurs de prouver qu'ils possèdent l'appareil avec lequel ils veulent s'inscrire à notre service. L'API Verify rend l'ensemble du processus d'authentification à deux facteurs très simple.

Il n'y a pas si longtemps, nous, développeurs Go, aurions dû effectuer manuellement tous les appels d'API nécessaires, mais en ces temps plus éclairés, nous disposons de notre tout nouveau SDK Go de Vonage pour nous faciliter la vie, alors mettons-le en place et configurons-le.

Pour utiliser le SDK Go, nous devons fournir notre clé API et notre secret, qui se trouvent dans le tableau de bord du développeur. Nous ne voulons pas insérer ces informations d'identification directement dans notre code, car toute personne ayant accès à notre clé et à notre secret peut effectuer des appels d'API à nos dépens. Nous allons donc configurer ces détails dans un fichier .env et utiliser le paquetage github.com/joho/godotenv pour lire ces valeurs dans les variables d'environnement.

Tout d'abord, créez le fichier .env dans le répertoire de votre projet :

VONAGE_API_KEY=<YOUR_API_KEY>
VONAGE_API_SECRET=<YOUR_API_SECRET>

Remplacer <YOUR_API_KEY> et <YOUR_API_SECRET> par votre propre clé d'API et votre secret.

Ensuite, exécutez go get pour installer dotenv et le SDK Vonage Go :

go get github.com/joho/godotenv go get github.com/vonage/vonage-go-sdk

En main.go écrivez du code pour lire vos informations d'identification API de Vonage dans le fichier .env et les utiliser pour instancier une instance du SDK Go de Vonage. VerifyClient:

package main

import (
	"log"
	"os"

	"github.com/joho/godotenv"
	"github.com/vonage/vonage-go-sdk"
)

var verifyClient *vonage.VerifyClient

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
		os.Exit(1)
	}

	apiKey := os.Getenv("VONAGE_API_KEY")
	apiSecret := os.Getenv("VONAGE_API_SECRET")

	auth := vonage.CreateAuthFromKeySecret(apiKey, apiSecret)
	verifyClient = vonage.NewVerifyClient(auth)

}

Construire l'interface utilisateur

Pour comprendre quelles pages notre application web doit présenter aux utilisateurs, considérons le flux de travail que nous allons mettre en œuvre :

The verification processThe verification process

Il en ressort que nous avons besoin des pages suivantes :

  • La page page d'accueil (/) : Si l'utilisateur est enregistré, nous affichons ici son nom et son numéro de téléphone.

  • La page page d'enregistrement (/register) : Où l'utilisateur peut entrer son nom et son numéro de téléphone pour s'inscrire à notre service.

  • Le code de vérification page de saisie (/enter-code) : L'utilisateur y saisit le code PIN envoyé à son téléphone par l'API Verify.

Nous créerons ces pages à l'aide de Modèles Go. Ceux-ci permettent de passer facilement des variables du code dans la page et de faire en sorte qu'un modèle en inclue d'autres en tant que "partiels", de sorte que vous n'ayez pas à dupliquer le contenu commun, comme les en-têtes, les menus, etc.

Tout d'abord, ajoutez le module html/template à la liste des importations dans main.go. Ensuite, créez les modèles suivants dans le répertoire tmpl les modèles suivants :

Le modèle de page de base

Il s'agit de la mise en page de base que tous nos modèles utiliseront. La directive {{template "main" .}} nous permet de remplir le corps de la page avec le contenu des autres modèles :

<!-- base.layout.gohtml-->
{{define "base"}}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Go Verify Demo</title>
  <link rel="stylesheet" href="/static/style.css">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300&family=Seymour+One&display=swap" rel="stylesheet">
</head>

<body>
  {{template "main" .}}
</body>

</html>
{{end}}

Le modèle de page d'accueil

Lorsque l'utilisateur s'est inscrit avec succès au service, cette page affiche son nom et son numéro de téléphone :

<!-- home.page.gohtml -->
{{template "base" .}}

{{define "main"}}
  <h1>Welcome to Acme Inc {{.Name}}!</h1>
  <p>Your registered phone number is: {{.Phone}}</p>
{{end}}

Le modèle de page d'inscription

Ce modèle comprend un formulaire dans lequel l'utilisateur peut saisir son nom et son numéro de téléphone pour s'inscrire au service :

<!-- register.page.gohtml -->
{{template "base" .}}

{{define "main"}}
  <h1>Acme inc.</h1>
  <p>Please register using your mobile/cell phone number for the exciting benefits our service provides!</p>
  <form action="/verify">
    <fieldset>
      <label for="name">Your name:</label>
      <input type="text" class="ghost-input" id="name" name="name" placeholder="Jane Smith" required/>   
      <label for="phone_number">Your mobile number:</label>
      <input type="text" class="ghost-input" id="phone_number" name="phone_number" placeholder="447700900001"required/>
      <button type="submit" class="ghost-button">Register</button>
    </fieldset>
  </form>
{{end}} 

Le modèle de la page de saisie du code

Cette page affiche un formulaire dans lequel l'utilisateur saisit le code qu'il a reçu de l'API Verify :

<!-- entercode.page.gohtml -->
{{template "base" .}}

{{define "main"}}
  <h1>Acme inc.</h1>
  <p>Please enter the code you received by SMS:</p>
  <form action="/check-code">
    <fieldset>
      <label for="pin_code">Enter PIN:</label>
      <input type="text" class="ghost-input" id="pin_code" name="pin_code" placeholder="123456" required><br><br>
    <button type="submit" class="ghost-button">Let's Go!</button>
    </fieldset>
  </form>
  
{{end}} 

Faire en sorte qu'il soit beau (ou presque)

Enfin, ajoutons quelques feuilles de style CSS pour que ces pages ressemblent à celles que nous avons investies quelques effort dans leur création. (Je ne suis pas un spécialiste de l'interface utilisateur, j'en ai peur, donc les PRs sont les bienvenus!)

Saisir le style.css fichier depuis le repo Github et incluez-le dans votre répertoire static dans votre répertoire.

Go doit être en mesure de servir ce contenu CSS statique à partir de votre système de fichiers local, vous devez donc indiquer à votre application comment procéder.

En main.go, importez d'abord le module net/http puis modifiez votre fonction main() comme suit :

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
		os.Exit(1)
	}

	apiKey := os.Getenv("VONAGE_API_KEY")
	apiSecret := os.Getenv("VONAGE_API_SECRET")

	auth := vonage.CreateAuthFromKeySecret(apiKey, apiSecret)
	verifyClient = vonage.NewVerifyClient(auth)

	mux := http.NewServeMux()
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

}

Gérer la session de l'utilisateur

Nous devons réfléchir à la manière dont nous allons savoir si un utilisateur s'est inscrit à notre service afin de pouvoir le connecter ou le rediriger vers la page d'inscription.

Pour ce faire, nous allons nous appuyer sur les cookies de session. Il existe un excellent module que nous pouvons utiliser pour gérer les cookies et les sessions du système de fichiers en Go : le module Gorilla sessions module.

Pour l'installer, exécutez :

go get github.com/gorilla/sessions

Ajoutez-le à votre liste d'importations dans main.go et créez le cookie de session. Pendant que vous y êtes, déclarez également un fichier struct appelé UserData qui stockera le nom et le numéro de téléphone d'un utilisateur enregistré. Nous passerons ce struct à notre modèle de page d'accueil afin que nous puissions afficher ces détails une fois que l'utilisateur s'est enregistré avec succès :

package main

import (
	"html/template"
	"log"
	"net/http"
	"os"

	"github.com/gorilla/sessions"
	"github.com/joho/godotenv"
	"github.com/vonage/vonage-go-sdk"
)

var (
	// Key must be 16, 24 or 32 bytes long (AES-128, AES-192 or AES-256)
	key   = []byte("super-secret-key")
	store = sessions.NewCookieStore(key)
)

// UserData - Info from session that we'll use in the UI
type UserData struct {
	Name  string
	Phone string
}

...

Définir les itinéraires

Nous devons maintenant réfléchir aux itinéraires à définir pour gérer notre flux de travail. Nous allons créer les routes suivantes :

  • Le point d'entrée point d'entrée de notre application (/). Il affichera la page d'accueil (si l'utilisateur est enregistré), ou redirigera vers la route /register (s'il ne l'est pas).

  • L'inscription d'inscription (/register). Elle affiche le formulaire d'inscription qui, une fois soumis, lance le processus de vérification en appelant la route /verify route.

  • La vérification de vérification (/verify). Elle envoie une demande de vérification à l'API Verify afin d'envoyer un code à l'appareil mobile de l'utilisateur. Elle redirige ensuite vers la route /enter-code route.

  • Le entrer le code (/enter-code) présente à l'utilisateur un formulaire contenant une zone de texte où il peut saisir le code PIN qu'il a reçu. Lorsqu'il soumet le formulaire, nous le redirigeons vers la route /check-code route.

  • Le code code de contrôle de l'itinéraire (check-code). Elle permet de comparer le code saisi avec celui envoyé par l'API Verify. S'il y a correspondance, nous stockons les détails de l'utilisateur dans la session et nous redirigeons vers la page d'accueil (/). S'il n'y a pas de correspondance, nous enregistrons une erreur dans la console. (Nous pourrions traiter ce problème de manière plus élégante, mais je laisse cet exercice au lecteur).

  • Les clair (/clear). Elle supprime le cookie de session afin que vous puissiez "désenregistrer" un utilisateur enregistré. Utile pour les tests !

Ouf ! Cela fait beaucoup de code à écrire. Heureusement, c'est assez simple.

Tout d'abord, définissez quelques gestionnaires pour les routes dans votre fonction main et lancez votre serveur à l'écoute des requêtes entrantes :

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
		os.Exit(1)
	}

	apiKey := os.Getenv("VONAGE_API_KEY")
	apiSecret := os.Getenv("VONAGE_API_SECRET")

	auth := vonage.CreateAuthFromKeySecret(apiKey, apiSecret)
	verifyClient = vonage.NewVerifyClient(auth)

	mux := http.NewServeMux()
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	mux.HandleFunc("/", home)
	mux.HandleFunc("/register", register)
	mux.HandleFunc("/verify", verify)
	mux.HandleFunc("/enter-code", enterCode)
	mux.HandleFunc("/check-code", checkCode)
	mux.HandleFunc("/clear", unregister)

	log.Println("Starting server on :5000")
	err = http.ListenAndServe(":5000", mux)
	log.Fatal(err)
}

Le gestionnaire de l'itinéraire domestique

Créez le home au-dessus de votre fonction main fonction. Ce gestionnaire est déclenché chaque fois qu'un utilisateur visite la racine de votre application web à l'adresse /.

Il charge le cookie de session et vérifie si la valeur registered est définie. Si c'est le cas, il stocke les informations du cookie dans une instance de UserData et l'utilise pour afficher la page d'accueil avec le nom et le numéro de téléphone de l'utilisateur.

Si ce n'est pas le cas, il redirige vers la route /register route :

func home(w http.ResponseWriter, r *http.Request) {

	session, _ := store.Get(r, "acmeinc-cookie")

	// Check if user is authenticated
	if auth, ok := session.Values["registered"].(bool); !ok || !auth {
		// Not authenticated, so user must register
		http.Redirect(w, r, "/register", 302)
	}

	userData := UserData{
		Name:  fmt.Sprintf("%v", session.Values["name"]),
		Phone: fmt.Sprintf("%v", session.Values["phoneNumber"]),
	}

	files := []string{
		"./tmpl/home.page.gohtml",
		"./tmpl/base.layout.gohtml",
	}

	/* Use the template.ParseFiles() function to read the files and store the
	templates in a template set.*/
	ts, err := template.ParseFiles(files...)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Internal Server Error", 500)
		return
	}

	err = ts.Execute(w, userData)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Internal Server Error", 500)
	}
}

Le gestionnaire de l'itinéraire d'enregistrement

L'itinéraire d'inscription affiche un formulaire permettant à l'utilisateur de saisir son nom et son numéro de téléphone pour s'inscrire au service.

Tout d'abord, ajoutez fmt à votre liste d'importations. Ensuite, créez le register au-dessus de votre main fonction :

func register(w http.ResponseWriter, r *http.Request) {
	files := []string{
		"./tmpl/register.page.gohtml",
		"./tmpl/base.layout.gohtml",
	}

	ts, err := template.ParseFiles(files...)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Internal Server Error", 500)
		return
	}

	err = ts.Execute(w, nil)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Internal Server Error", 500)
	}
}

Le gestionnaire d'itinéraires de vérification

Lorsque l'utilisateur a rempli ses données d'inscription et cliqué sur le bouton "S'inscrire", l'application appelle l'itinéraire /verify route. C'est ici que nous créons la demande initiale à l'API Verify pour générer un code et l'envoyer au téléphone de l'utilisateur.

Lorsque vous soumettez une demande à l'API Verify, celle-ci renvoie un élément request_id pour identifier cette demande particulière. Vous avez besoin de cet identifiant lorsque vous vérifiez le code saisi par l'utilisateur, et vous le stockez donc dans une variable globale :

package main

import (
	...
)

var (
	...
)

// UserData: Info from session that we'll use in the UI
type UserData struct {
	...
}

var verifyClient *vonage.VerifyClient
var requestID string

L'initiation de cette requête est très simple à l'aide du SDK Go. Nous appelons la méthode VerifyClient.Request en indiquant le numéro de téléphone de l'utilisateur, le texte que nous voulons voir apparaître dans le SMS de vérification et quelques options pour personnaliser le processus de vérification.

Dans cet exemple, les options spécifiées sont les suivantes :

  • CodeLength: Il s'agit de la longueur du code que nous envoyons à l'utilisateur. La valeur par défaut est de quatre chiffres, mais nous générons un code à six chiffres.

  • Lg: Spécifie la langue dans laquelle nous envoyons le SMS de vérification, à partir de la liste des langues disponibles.

  • WorkflowID: L'API Verify tente à plusieurs reprises d'envoyer un code de vérification. La manière et le moment où ces tentatives sont effectuées dépendent du flux de travail que vous avez choisi. Nous utilisons le flux de travail avec un ID de 4qui envoie le code par SMS et attend deux minutes pour que le code soit vérifié. S'il n'est pas vérifié après ce délai, il envoie à nouveau le code et attend trois minutes supplémentaires avant d'annuler le processus. D'autres flux de travail utilisent une combinaison de SMS et d'appels vocaux avec synthèse vocale pour délivrer le code de vérification.

Nous allons également stocker les informations que l'utilisateur a saisies dans notre cookie de session.

Ecrivez le code pour le verify au-dessus de votre fonction main fonction :

func verify(w http.ResponseWriter, r *http.Request) {

	session, _ := store.Get(r, "acmeinc-cookie")
	// retrieve user's name and phone number from the submitted form
	userName := r.URL.Query().Get("name")
	phoneNumber := r.URL.Query().Get("phone_number")
	session.Values["name"] = userName
	session.Values["phoneNumber"] = phoneNumber
	session.Save(r, w)
	log.Println("Verifying...." + userName + " at " + phoneNumber)
	response, errResp, err := verifyClient.Request(phoneNumber, "GoTest", vonage.VerifyOpts{CodeLength: 6, Lg: "en-gb", WorkflowID: 4})

	if err != nil {
		fmt.Printf("%#v\n", err)
	} else if response.Status != "0" {
		fmt.Println("Error status " + errResp.Status + ": " + errResp.ErrorText)
	} else {
		requestID = response.RequestId
		fmt.Println("Request started: " + response.RequestId)
		// redirect to "check" page
		http.Redirect(w, r, "/enter-code", 302)
	}
}

Le gestionnaire de l'itinéraire du code d'entrée

Si tout s'est déroulé comme prévu, l'utilisateur recevra un SMS contenant un code PIN. Notre /enter-code fournira un formulaire permettant à l'utilisateur d'introduire ce code.

Ajoutez le enterCode à votre application :

func enterCode(w http.ResponseWriter, r *http.Request) {
	files := []string{
		"./tmpl/entercode.page.gohtml",
		"./tmpl/base.layout.gohtml",
	}

	ts, err := template.ParseFiles(files...)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Internal Server Error", 500)
		return
	}

	err = ts.Execute(w, nil)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Internal Server Error", 500)
	}
}

Le gestionnaire de l'itinéraire du code de contrôle

Lorsque l'utilisateur a saisi le code qu'il a reçu par SMS, nous devons effectuer une demande de vérification Verify pour nous assurer que le code qu'il a saisi est le même que celui qui lui a été envoyé. Nous utilisons la méthode VerifyClient.Check pour cela, en passant l'ID de la requête que nous avons faite dans le gestionnaire de route verify et le code qu'ils ont saisi dans notre page.

Si le code correspond, nous définissons la valeur du cookie de session registered à la valeur du cookie de session true et nous redirigeons vers la page d'accueil. Dans le cas contraire, un message d'erreur est affiché dans la console :

func checkCode(w http.ResponseWriter, r *http.Request) {
	// Retrieve the PIN code that the user entered
	session, _ := store.Get(r, "acmeinc-cookie")
	pinCode := r.URL.Query().Get("pin_code")
	response, errResp, err := verifyClient.Check(requestID, pinCode)

	if err != nil {
		fmt.Printf("%#v\n", err)
	} else if response.Status != "0" {
		fmt.Println("Error status " + errResp.Status + ": " + errResp.ErrorText)
	} else {
		fmt.Println("Request complete: " + response.RequestId)
		// Set user as authenticated and return to home page
		session.Values["registered"] = true
		session.Save(r, w)
		http.Redirect(w, r, "/", 302)
	}
}

Le gestionnaire de l'itinéraire de dégagement

Cela sera utile pour les tests. Il vous permet de réinitialiser l'utilisateur en envoyant une requête à http://localhost:5000/clearce qui supprime le cookie de session.

Créez le unregister comme suit :

func unregister(w http.ResponseWriter, r *http.Request) {
	// Delete the session
	session, _ := store.Get(r, "acmeinc-cookie")
	session.Options.MaxAge = -1
	session.Save(r, w)
	http.Redirect(w, r, "/", 302)
}

Essayez-le !

Vous avez terminé ! Il est maintenant temps de tester votre application.

  1. Lancez l'application en exécutant go run main.go

  2. Visitez http://localhost:5000 dans votre navigateur

  3. Saisissez votre nom et votre numéro de téléphone, y compris l'indicatif, mais en omettant les zéros initiaux. Par exemple, le numéro de téléphone mobile britannique 07700900001 doit être saisi comme suit 447700900001:

    Enter your name and phone numberRegistration page

  4. Vous recevrez un SMS contenant un code à six chiffres :

    SMS containing PIN codeThe verification code, sent by SMS

  5. Saisissez ce code dans l'application :

    Enter the code into the appEntering the verificaiton code

  6. Vous êtes enregistré et renvoyé à la page d'accueil :

    ![Signé à la page d'accueil]("Signé à la page d'accueil")

Quelle est la prochaine étape ?

Avec un peu de chance, vous avez vu à quel point il est facile d'utiliser l'API Verify et le SDK Go pour activer l'authentification à deux facteurs dans vos applications. En fait, l'ensemble du processus de vérification n'a nécessité que quelques lignes de code ! Le gros du travail a consisté à créer et à gérer l'interface utilisateur.

Note: Si vous n'avez pas réussi à suivre le tutoriel, vous pouvez trouver le code source complet de ce tutoriel sur GitHub.

Vous pensez que cette démo pourrait être améliorée ? Je suis d'accord ! Voici celles qui me viennent à l'esprit :

  • La sortie peu gracieuse lorsque l'utilisateur saisit le mauvais code. Au lieu de cela, vous pourriez rediriger l'utilisateur vers la page de saisie du code et simultanément vérifier l'état d'avancement de la demandevoire même annuler une demande en cours après deux tentatives infructueuses.

  • Le format dans lequel les utilisateurs doivent entrer leur numéro de téléphone. Les API de Vonage s'attendent à ce que les numéros de téléphone soient au format E.164mais il n'y a aucune raison d'infliger cela à vos utilisateurs ! Vous pouvez leur demander d'entrer leur numéro local et leur pays dans une liste déroulante et d'utiliser l'API Number Insight API de Vonage de Vonage pour le convertir dans le bon format. Cela permettrait également de vérifier que le numéro saisi par l'utilisateur est légitime.

Nous espérons que vous êtes aussi enthousiastes que nous à propos de notre nouveau SDK Go. Pour en savoir plus sur ce dernier et sur l'API Verify, consultez les ressources suivantes :

Partager:

https://a.storyblok.com/f/270183/384x384/637d0e41eb/marklewin.png
Mark LewinAnciens de Vonage

Ancien rédacteur technique chez Vonage. Aime jouer avec les API et les documenter.