https://d226lax1qjow5r.cloudfront.net/blog/blogposts/using-vonage-apis-with-mongodb-atlas-part-2/mongodb_vonage_p2.png

Verwendung von Vonage APIs mit MongoDB Atlas - Teil 2

Zuletzt aktualisiert am May 4, 2023

Lesedauer: 9 Minuten

In dieser Serie:

Wir setzen unseren Tauchgang in MongoDB Atlas und seine Verwendung mit verschiedenen Vonage-APIs fort. In Teil 1 haben wir uns angeschaut, was MongoDB Atlas genau ist und welche Dienste es bietet. In Teil 2 werden wir in die Beispielanwendung eintauchen, um zu sehen, wie wir MongoDB zur Unterstützung unseres Registrierungsprozesses verwenden und Vonage Verify für zusätzliche Benutzersicherheit einbinden können.

Was ist Vonage Verify?

Vonage Verify ist eine Zwei-Faktoren-Authentifizierung Dienst, den Vonage als API bereitstellt. Er ermöglicht es Ihnen, einen einfachen API-Aufruf zu tätigen, um einen Code an einen Benutzer zu senden, und dann dessen Gültigkeit mit einem weiteren API-Aufruf zu überprüfen. Dies bietet zusätzliche Sicherheit, da sichergestellt wird, dass der Benutzer nicht nur sein Passwort kennt, sondern auch über ein physisches Gerät verfügt, das er uns mitgeteilt hat, um den Code zu empfangen. Da die meisten Menschen ein mobiles Gerät besitzen, kann man davon ausgehen, dass sie darauf Zugriff haben, um den Code zu empfangen.

Vonage Verify generiert den Code und kontaktiert den Kunden in Ihrem Namen. Wir werden auch versuchen, den Kunden mehrmals auf verschiedene Arten zu kontaktieren. Wenn Sie beispielsweise nicht innerhalb eines bestimmten Zeitraums versuchen, den Code von einem Kunden zu validieren, werden wir versuchen, den Kunden mit einer automatischen Nachricht anzurufen, um ihm den Code mitzuteilen. Wenn er ihn dann immer noch nicht eingibt oder nicht ans Telefon geht, versuchen wir es erneut per SMS. Sie können über so genannte Workflows steuern, wie wir versuchen, den Kunden zu kontaktieren.

Unser altes Verify-Produkt unterstützt SMS und Voice zur Kontaktaufnahme mit dem Kunden. Verify Produkt unterstützt SMS, Voice, WhatsApp, E-Mail und gerätebasierte Authentifizierungskanäle mit vollständig anpassbaren Workflows. Beide Produkte ersparen Ihnen das manuelle Versenden von Benachrichtigungen an Ihre Kunden und das Nachverfolgen ihrer Antworten. Sie müssen sich auch keine Sorgen mehr über das Versenden von Beschwerdemeldungen machen oder darüber, dass diese in den Spam-Filtern der Telefongesellschaften hängen bleiben.

Sie senden einfach eine API-Anfrage an uns, wir senden den Code, und Sie verifizieren ihn.

Erstellen einer Datenbank

Damit unsere Demo funktioniert, brauchen wir etwas zu essen, das die Benutzer bestellen können! Das Hinzufügen von Informationen zu einer MongoDB-Datenbank ist etwas anders als das Hinzufügen von Daten zu einem traditionellen relationalen Datenbankmanagementsystem wie Postgres oder MySQL. MongoDB ist ein dokumentenbasiertes System. Anstatt eine Datenbank mit Tabellen zu erstellen, werden wir eine Datenbank mit Collections erstellen. In diesen Collections werden Dokumente gespeichert, d. h. spezielle JSON-ähnliche Dokumente, nach denen wir suchen und die wir verwenden können.

Lassen Sie uns unsere erste Datenbank erstellen. Klicken Sie in Ihrem MongoDB Atlas Dashboard auf die Schaltfläche Sammlungen durchsuchen Schaltfläche für Ihren Cluster.

MongoDB DashboardMongoDB Dashboard

So erhalten Sie einen Überblick über alle Informationen in Ihrem Cluster. Im Moment ist sie noch recht kahl, da wir keine Datenbanken oder Informationen haben. Fügen wir ein paar Lebensmittel hinzu, die die Benutzer kaufen können. Klicken Sie auf die Schaltfläche Eigene Daten Schaltfläche.

Adding DataAdding Data

Es wird dann nach dem Namen der Datenbank und einem Sammlungsnamen gefragt. Für unsere Demo wollen wir "restaurant_pos_demo" für die Name der Datenbank und "Inventar" für den Name der Sammlung. Die Demo ist bereits so eingerichtet, dass sie nach dieser Datenbank und Sammlung sucht. Stellen Sie also sicher, dass Sie diese Namen anstelle eines benutzerdefinierten Namens verwenden. Sobald Sie dies eingegeben haben, klicken Sie auf die Schaltfläche Erstellen Schaltfläche.

Create new CollectionCreate new Collection

Jetzt können wir einige Daten eingeben. Klicken Sie auf die Schaltfläche Dokument einfügen Schaltfläche. Dadurch wird der Dokumenteditor aufgerufen. Er bietet eine Reihe von Dropdowns für die Eingabe von Informationen, aber wir können auch einfach ein Dokument einfügen. Klicken Sie auf die Schaltfläche {} Schaltfläche oben, um in den Texteingabemodus zu wechseln, und fügen Sie den kleinen JSON-Block für das Hamburger-Dokument ein. Klicken Sie auf Einfügenund das Inventarobjekt wird gespeichert. Wiederholen Sie diesen Vorgang, aber fügen Sie beim zweiten Mal das Soda-Dokument ein.

// Document 1
{
  "name": "Hamburger",
  "price": 995
}

// Document 2
{
  "name": "Soda",
  "price": 199
}

Document EditorDocument Editor

Sobald Sie die beiden Dokumente eingegeben haben, können Sie sie in der Datenbankansicht sehen. Dieser Editor eignet sich hervorragend, um mit Dokumenten und Daten herumzuspielen, während Sie Ihre Datenbank aufbauen, und kann in der Entwicklungsphase viel Zeit bei der Fehlersuche sparen. In einer größeren Produktionsumgebung können Sie Abfragen ausführen, um Daten herauszufiltern, aber im Moment ist dies eine gute Möglichkeit, unsere Daten schnell einzugeben.

DocumentsDocuments

Einrichten der Demo

Nun, da wir einige Daten haben, können wir unsere Demo verkabeln. Klonen Sie die Demo von https://github.com/Vonage-Community/sample-mongodb-vonage-integration-restaurant-demo. Es gibt zwei Ordner, den "webapp"-Ordner mit dem Quellcode und den "app-service"-Ordner mit einigen MongoDB-Konfigurationen, die wir später verwenden werden. Wechseln Sie zunächst in den Ordner "webapp" und öffnen Sie ihn in Ihrem bevorzugten Editor.

Wir müssen einige Konfigurationsdetails hinzufügen, damit die Anwendung weiß, wie sie mit Ihrem MongoDB-Cluster kommunizieren kann. Erstellen Sie eine Kopie der .env.dist Datei im Repository und nennen Sie sie .env. Diese Datei enthält alle Informationen, die für Ihre Installation erforderlich sind.

Öffnen Sie .env und nehmen Sie die folgenden Änderungen vor:

  1. Ändern Sie "ENABLE_VERIFY" auf "1", damit wir die Vonage Verify API in Aktion sehen können

  2. Setzen Sie "VONAGE_API_KEY" auf den Vonage API-Schlüssel, der in Ihrem Vonage Customer Dashboard verfügbar ist.

  3. Setzen Sie "VONAGE_API_SECRET" auf das Vonage API-Geheimnis, das Sie in Ihrem Vonage Customer Dashboard finden.

  4. Ändern Sie den "JWT_SIGNING_KEY" in einen zufälligen Wert. Die Zeichenkette ist nicht wirklich wichtig, aber wir werden sie später für die Validierung von API-Aufrufen verwenden.

Wir müssen auch den Wert von "MONGODB_DSN" auf die Verbindungszeichenfolge für Ihren Cluster setzen. Um diesen Wert zu finden, gehen Sie zu Ihrem MongoDB Atlas Dashboard und klicken Sie auf die Schaltfläche Verbinden Schaltfläche für Ihren Cluster. Klicken Sie in dem Pop-up-Fenster auf Verbinden Sie Ihre Anwendung. Daraufhin wird ein Bildschirm mit Ihrer Verbindungszeichenfolge angezeigt. Kopieren Sie diesen Wert, und fügen Sie ihn in den Wert für "MONGODB_DSN" in .env. Stellen Sie sicher, dass Sie den <password> Teil in das Passwort für Ihren Cluster ändern.

Connecting to the applicationConnecting to the application

Wir sollten jetzt in der Lage sein, die Demo zu starten!

Ausführen der Demo

Die Demo selbst wurde mit Vite, Vue.js und Typescript erstellt. Um die Demo auszuführen, müssen wir sowohl die Front-End-Client-Anwendung als auch eine Back-End-Server-Anwendung ausführen. Öffnen Sie zwei Kommandozeilen-Terminals.

Im ersten Terminal, im Ordner webapp/ Ordner den Befehl npm ci um alle Abhängigkeiten zu installieren, und führen Sie dann npm run dev. Wenn alles korrekt abläuft, sollten Sie einen Bildschirm erhalten, der "Vite <version>" und dann einen Link für Lokaleerhalten, der wahrscheinlich auf http://localhost:5173. Ihr Link kann etwas anders aussehen, wenn Sie andere Dinge haben, die auf Port 5173 hören.

Navigieren Sie im zweiten Terminal zu webapp/server. Wie im anderen Fenster führen Sie npm ci um alle Abhängigkeiten zu installieren, und führen Sie dann npm run dev. Dieser Bildschirm sollte nodemon starten und schließlich "Server Started" anzeigen. Wenn Sie eine Fehlermeldung sehen, dass keine Verbindung hergestellt werden kann, überprüfen Sie die Verbindungszeichenfolge Ihres MongoDB-Clusters.

Starting the demoStarting the demo

Öffnen Sie Ihren Browser, und navigieren Sie zu http://localhost:5173/website/login (ersetzen Sie die Portnummer durch diejenige, die laut Vite für Sie läuft). Sie sollten mit dem folgenden Anmeldebildschirm begrüßt werden!

Login PageLogin Page

Testen von Verify

Wir haben derzeit keine Benutzer, also legen wir einen an. Klicken Sie auf die Oder registrieren Sie sich für Geschmack Link auf der Seite. Geben Sie einen Benutzernamen, ein Passwort und eine Mobiltelefonnummer ein. Ihre Nummer sollte die Landesvorwahl enthalten und keine Bindestriche enthalten. Wir senden einen Zwei-Faktor-Authentifizierungscode an diese Handynummer als Teil der Benutzeranmeldung. Stellen Sie also sicher, dass Sie eine tatsächliche Handynummer und keine Google Voice-Nummer verwenden. Wenn Sie in den USA leben, sieht ein Beispiel so aus: "15556661234".

Sobald Sie Ihre Benutzerinformationen eingegeben haben, klicken Sie auf Registrieren.

Sie sollten sich nun anmelden können. Geben Sie Ihren Benutzernamen und Ihr Passwort ein, mit denen Sie sich gerade registriert haben. Wenn die Authentifizierung erfolgreich war, sollten Sie zu einem kleinen Formular weitergeleitet werden, das Sie zur Eingabe Ihres 2FA-Codes auffordert.

M2FA Form2FA Form

Nach ein paar Sekunden sollten Sie eine SMS mit einem vierstelligen Code erhalten. Geben Sie diesen Code in das Formular ein und klicken Sie auf Absenden. Wenn alles funktioniert, sehen Sie einen Bestellbildschirm mit unserem Hamburger und unserer Limonade!

Wie funktioniert das?

Wenn sich der Benutzer anmeldet, sendet unsere Vue.js-Client-Anwendung den Benutzernamen und das Passwort an unseren Backend-Server, und zwar /api/website/authenticate. Diese Route verbindet sich direkt mit unserem MongoDB-Cluster und findet den Benutzer in einer users Sammlung. Als wir einen neuen Benutzer registrierten, erstellte MongoDB automatisch die Sammlung für uns und speicherte ein Dokument für den Benutzer. Wir rufen dieses Dokument ab und vergleichen dann das Passwort mit der im Dokument gespeicherten Hash-Kopie.

Der MongoDB Node.js-Client ist ein fließender Client, d. h. wir können Methodenaufrufe aneinanderreihen, um eine Abfrage zu erstellen. Die Zeile:

const userRecord = await client.db('restaurant_pos_demo').collection('users').findOne({ username });

weist den MongoDB-Client an, unsere Datenbank "restaurant_pos_demo" zu verwenden, in der Sammlung "users" zu suchen und ein Dokument mit dem in der Anfrage angegebenen "username" zu finden. Da wir das Passwort als bcrypt-Hash gespeichert haben, können wir mit bcrypt.compare() verwenden, um das vom Benutzer angegebene Kennwort mit dem im Benutzerdokument gespeicherten Kennwort zu vergleichen. Wenn sie übereinstimmen, hat der Benutzer das richtige Kennwort eingegeben!

// webapp/server/server.ts

app.all('/api/website/authenticate', async (req, res) => {
    const { username, password } = req.body
    const userRecord = await client.db('restaurant_pos_demo').collection('users').findOne({ username });

    if (userRecord) {
        await bcrypt.compare(password, userRecord.password)
            .then(async (match) => {
                if (match) {
                    const token = jwt.sign({user_id: userRecord._id }, process.env.JWT_SIGNING_KEY, { expiresIn: '15m'})
                    let verifyId = {request_id: 'abcd'};
                    if (process.env.ENABLE_VERIFY === "1") {
                        verifyId = await vonage.verify.start({number: userRecord.phone, brand: 'Vonage Restaurant'})
                        console.log(verifyId);
                    } else {
                        console.log('Verify Disabled');
                    }
                    
                    res.status(200).json({ token, verifyId: verifyId.request_id })
                } else {
                    res.status(401).send()
                }
            })
        return
    }

    res.status(401)
    res.send()
    return
})

Wir generieren dann ein temporäres JWT, das wir an die Vue.js-Anwendung zurücksenden. Unsere Vue.js-Anwendung wird dieses temporäre JWT verwenden, wenn der Benutzer den Code in der clientseitigen Anwendung eingibt. Wenn Verify in der Demo mit "ENABLE_VERIFY" aktiviert ist, verwenden wir das Vonage Node.js SDK um die Verify API aufzurufen. Wir übergeben die Telefonnummer des Benutzers und setzen die Marke auf "Vonage Restaurant". Wenn der Benutzer eine SMS-Nachricht oder einen Sprachanruf erhält, wird er als "Vonage Restaurant" identifiziert, wenn er sie erhält.

Die Vonage-API gibt eine "Request-ID" zurück, die wir auch an das Frontend zurücksenden und zur Überprüfung des Codes vom Benutzer verwenden. Anschließend senden wir das temporäre JWT-Token und die Request-ID zurück an die Vue.js-App.

Sobald wir verifiziert haben, dass der Benutzer derjenige ist, der er vorgibt zu sein, haben wir das Vue.js-Formular so geändert, dass es nach dem 2FA-Code fragt. Wenn der Benutzer den Code eingibt, sendet die Vue.js-App eine Anfrage an /api/website/authenticate/verify mit dem Token, der Verify Request ID und dem Code, den der Benutzer eingegeben hat.

Das JWT enthält die Dokument-ID des Benutzers, also entschlüsseln wir das Token und suchen den Benutzer in MongoDB wieder. Wenn wir ihn finden, rufen wir die Verify API auf, aber dieses Mal verwenden wir die check() Methode und senden die Anfrage-ID und den Code mit. Die API gibt einen Erfolg zurück, wenn der Code übereinstimmt. Wenn er übereinstimmt, generieren wir ein echtes JWT mit einer längeren Gültigkeitsdauer und geben es an die Vue.js-Anwendung zurück.

// webapp/server/server.ts

app.all('/api/website/authenticate/verify', async (req, res) => {
    const { token, verifyId, tfaPin } = req.body
    const decodedToken = jwt.decode(token)
    const userRecord = await client.db('restaurant_pos_demo').collection('users').findOne({ _id: new ObjectId(decodedToken.user_id) });

    if (userRecord) {
        if (process.env.ENABLE_VERIFY === "1") {
            await vonage.verify.check(verifyId, tfaPin)
                .then(resp => {
                    console.log(resp)
                    const token = jwt.sign({user_id: userRecord._id }, process.env.JWT_SIGNING_KEY, { expiresIn: '2h'})
                    res.status(200).json({ token })
                })
                .catch(err => {
                    console.error("there was an error", err);
                })
            return
        } else {
            const token = jwt.sign({user_id: userRecord._id }, process.env.JWT_SIGNING_KEY, { expiresIn: '2h'})
            res.status(200).json({ token })
        }
    }

    res.status(500)
    res.send()
    return
})

Die Vue.js-Anwendung weiß, dass wir vollständig authentifiziert sind, sobald sie das richtige JWT zurückerhält. Sie speichert dieses Token in einem globalen Speicher namens "authenticationStore", und der Rest der Anwendung wird dieses JWT verwenden, um den Benutzer für alle weiteren API-Aufrufe zu authentifizieren.

// src/views/Website/Login.vue

const verify = async() => {
    fetch(import.meta.env.VITE_API_URL + '/api/website/authenticate/verify', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            token: tempJWT.value,
            verifyId,
            tfaPin: tfaPin.value
        })
    })
        .then(resp => resp.json())
        .then(async (json) => {
            console.log(json)
            authStore.setToken(json.token)
            router.push({ name: 'website.order' });
            
            return
        })
        .catch(err => console.log(err)); 
}

Schlussfolgerung

Wenn Sie bereits einen Authentifizierungsschritt in Ihrer Anwendung haben, erfordert das Hinzufügen von Vonage Verify nur ein paar zusätzliche Codezeilen. Für unsere Vue.js-Anwendung bedeutete dies einen zusätzlichen Aufruf an unser Backend und ein neues Formular, und auf der Serverseite mussten wir nur den API-Aufruf zum Senden des Codes und dann eine neue Route zur Verifizierung des Codes durchführen. Da Vonage die ganze Arbeit des Generierens, Sendens und Überprüfens des Codes übernimmt, sind die Auswirkungen auf unsere Codebasis minimal. Die Flexibilität des dokumentenbasierten Speichers von MongoDB bedeutete, dass wir keine Datenbankmigrationen durchführen mussten und schnell den Code zum Einfügen eines neuen Benutzers und zum Durchführen der Abfragen schreiben konnten.

Jetzt, wo sich unsere Nutzer einloggen können, sollten sie etwas zu essen bestellen!

Im nächsten Abschnitt werden wir uns die Verwendung von MongoDB zum Speichern der Bestellung und die Vonage SMS API zum Senden einer Bestellbestätigung ansehen. Wir werden auch einen Blick auf die Verwendung der Vonage Meetings API werfen, um unserer Anwendung schnell Videokonferenzen für Kundendienstlösungen hinzuzufügen.

Teilen Sie:

https://a.storyblok.com/f/270183/384x384/3bc39cbd62/christankersley.png
Chris TankersleyTooling-Manager für Entwicklerbeziehungen

Chris ist Developer Relations Tooling Manager und leitet das Team, das Ihre Lieblingstools entwickelt. Er programmiert seit mehr als 15 Jahren in verschiedenen Sprachen und für verschiedene Projekttypen, von der Kundenarbeit bis hin zu Big-Data-Großsystemen. Er lebt in Ohio, verbringt seine Zeit mit seiner Familie und spielt Video- und TTRPG-Spiele.