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

Verwendung von Vonage APIs mit MongoDB Atlas - Teil 4

Zuletzt aktualisiert am May 16, 2023

Lesedauer: 13 Minuten

In dieser Serie:

Wir setzen die Untersuchung von MongoDB Atlas und seiner Verwendung mit verschiedenen Vonage-APIs fort. In Teil 1 haben wir einen Blick darauf geworfen, was MongoDB Atlas ist und welche Dienste es bietet. In Teil 2 haben wir Vonage Verify verwendet, um die Benutzersicherheit bei der Authentifizierung zu erhöhen. Teil 3 drehte sich um die Kontaktaufnahme mit dem Kunden für seine Bestellung und was wir tun können, wenn Kunden mit dem Restaurant sprechen müssen. In Teil 4 werden wir das Benutzerauthentifizierungssystem von Atlas in Betrieb nehmen.

Auslagerung der Benutzerauthentifizierung

Ein gemeinsamer Bereich von Webanwendungen ist die Notwendigkeit, Benutzer zu authentifizieren. Frameworks helfen dabei, einen Teil davon zu bewältigen, aber jede Anwendung baut ähnlichen Code, um eine Sache zu tun - die Anmeldedaten eines Benutzers zu bestätigen. MongoDB Atlas verfügt über ein eingebautes System zur Benutzer zu authentifizieren und zu verwalten.

Dieses System unterscheidet sich von der Authentifizierung, die wir für MongoDB durchführen, und ist ein Dienst, den Atlas bereitstellt. Sie können Benutzer über Atlas als Authentifizierungsdienst eines Dritten (für Ihre Anwendung) verwalten. Mit Atlas können Sie viele verschiedene Authentifizierungsarten sicher unterstützen.

Um dies zu demonstrieren, verwendet das administrative Backend unserer Demo die Atlas-Authentifizierung anstelle von Verify. Mit diesem Backend können wir den Bestand, den wir den Nutzern zeigen, und die eingegangenen Bestellungen verwalten. Es ermöglicht uns auch die Teilnahme an Videokonferenzen, die von Kunden gestartet wurden. Außerdem können wir so sehen, was passiert, wenn wir den MongoDB-Zugriff in unsere Anwendung einbetten wollen, anstatt uns auf eine Backend-API zu verlassen.

Einrichten der Authentifizierung

Atlas unterstützt sowohl eine Web-UI als auch Konfigurationsdateien für viele anwendungsspezifische Funktionen. Wir werden die Web-UI für das Tutorial zur Konfiguration verwenden, aber Sie können auch die mitgelieferten Beispieldateien im Demo-Repository verwenden. Diese Dateien funktionieren mit dem Realm CLI-Werkzeugund wir haben sie für Sie bereitgestellt, damit Sie sie mit der Web-UI vergleichen können. Wenn Sie gerade erst anfangen, empfehle ich Ihnen, die Web-UI zu verwenden, aber in einer verwalteten Anwendung sollten Sie die Konfiguration speichern und die Realm CLI verwenden, um Konfigurationsänderungen zu verteilen. Die Demo enthält einen app-service/ Ordner mit Beispieldateien, die Sie für die ersten Schritte bearbeiten können.

Atlas Apps sind eine Kombination aus Konfigurationsdetails und bereitgestelltem Code. Die Apps-Schnittstelle erleichtert die Arbeit mit den Einstellungen und dem Code, den ein Entwickler auf Atlas-Dienste ausgelagert hat.

Lassen Sie uns zunächst die Web-Benutzeroberfläche verwenden. Sobald Sie sich bei Ihrem Projekt angemeldet haben, klicken Sie in der oberen sekundären Navigationsleiste auf "App Services". Daraufhin wird eine Liste der konfigurierten Anwendungsprojekte angezeigt. Wenn dies die erste Anwendung ist, mit der Sie arbeiten, öffnet sich ein Fenster, das Sie zu den App Services führt. Wählen Sie vorerst "Build your own app", da wir für das Tutorial alles selbst erledigen werden.

New Atlas App dialogNew Atlas App dialog

Der nächste Bildschirm enthält einige Konfigurationsfragen. Unsere Datenquelle, d. h. der von uns verwendete Cluster, sollte ausgefüllt werden. Wählen Sie denjenigen aus, den Sie für den Lehrgang verwenden, wenn Sie mehrere Cluster haben. Sie können auch den Namen der Anwendung ändern. Ich werde die Anwendung "Frontend" nennen, da dieser Anwendungsdienst unser JavaScript-Frontend für die Verwaltungsseiten verwalten wird. Klicken Sie auf . App-Dienst erstellen um fortzufahren, und dann Anleitungen schließen um das Jumpstart-Fenster zu schließen.

Dies bringt uns zum Apps-Dashboard für unsere Frontend-Anwendung. Wie Sie sehen, können Sie mit einer Atlas-App viele Dinge tun, aber im Moment konzentrieren wir uns auf die Verwendung der Benutzerauthentifizierung. Klicken Sie unter dem Abschnitt Data Access" in der Seitenleiste auf Authentifizierung damit wir mit dem Einrichten beginnen können.

User authentication optionsUser authentication options

Wie bereits erwähnt, unterstützt Atlas mehrere Arten der Authentifizierung. Im Moment werden wir uns nur um "E-Mail/Passwort" kümmern. Klicken Sie auf die Schaltfläche Bearbeiten um mit dem Einrichten zu beginnen.

Schalten Sie auf der Konfigurationsseite die Option "Provider Enabled" ein. Für das Tutorial werden wir neue Benutzer automatisch bestätigen, also wählen Sie auch "Automatically confirm users". In einer Produktionsanwendung werden Sie wollen, dass der Benutzer seine E-Mail verifiziert, um zu bestätigen, dass die E-Mail-Adresse existiert, aber wir können diesen Schritt für jetzt überspringen. Sie müssen eine "URL zum Zurücksetzen des Kennworts" eingeben, auf die wir hier nicht näher eingehen werden, aber geben Sie "https://example.com/reset" ein, um das Formular auszufüllen. Klicken Sie auf Entwurf speichern wenn Sie fertig sind.

Email/Password optionsEmail/Password options

Warten Sie, "Entwurf speichern?!" Wenn Sie das eingeblendete Fenster überspringen, gelten alle Änderungen, die Sie in Atlas vornehmen, als Entwurfsänderungen. Sie können eine Reihe von verschiedenen Entwurfsstadien erstellen und diese bereitstellen, wenn alles eingerichtet ist. Alle diese Informationen werden in Konfigurationsdateien gespeichert, die über die Realm CLI gepusht und gezogen werden können. Die oben erwähnten Dateien werden in app-service/ als Beispiele.

Sobald Sie eine Änderung vorgenommen haben, sehen Sie oben auf der Seite ein Banner mit der Aufschrift "Es wurden Änderungen vorgenommen" und einer Schaltfläche zur Überprüfung. Klicken Sie nun auf Entwurf prüfen & bereitstellen. Sie sehen einen JSON-Blob, der einen Textvergleich zwischen den alten und neuen Einstellungen darstellt. Dies wird Ihnen sehr vertraut vorkommen, wenn Sie das Pull-Request-System von GitHub verwendet haben. Da wir gerade diese Änderung vorgenommen haben, klicken Sie auf Bereitstellen. Diese Einstellungen werden an den App-Dienst übertragen, und wir können die Authentifizierung verwenden.

Deployment Diff dialogDeployment Diff dialog

Jetzt brauchen wir einen Benutzer. Klicken Sie auf App-Benutzer in der Seitenleiste, und dann auf die Schaltfläche Neuen Benutzer hinzufügen Schaltfläche. Geben Sie eine gültige E-Mail-Adresse und ein Passwort ein und klicken Sie dann auf erstellen.. Da die Erstellung von Benutzern auf diese Weise nicht skalierbar ist, gibt es Optionen zur programmgesteuerten Erstellung von Benutzern durch einen Anmeldeprozess, aber für den Moment werden wir einen Benutzer verwenden, den wir von Hand erstellen.

An diesem Punkt ist die Authentifizierung für unsere Anwendung konfiguriert. Wir könnten das MongoDB Realm SDK verwenden, um einen Benutzer zu authentifizieren, aber unser aktueller Benutzer ist nichts weiter als eine E-Mail-Adresse und ein Passwort. Wir können keine zusätzlichen Informationen speichern oder angeben, dass der Benutzer ein administrativer Benutzer ist. An dieser Stelle kommen die benutzerdefinierten Benutzerdaten ins Spiel. Wir können einen Benutzer mit einer Dokumentensammlung verknüpfen, die zusätzliche Benutzerinhalte wie Name, Telefon oder sogar die Kennzeichnung als Administrator enthält.

Klicken Sie auf Benutzereinstellungen. Daraufhin wird die Konfigurationsseite für die Verknüpfung unserer Benutzerdaten angezeigt.

Custom User Information settingsCustom User Information Settings

Aktivieren Sie die Option "Benutzerdefinierte Daten aktivieren" und wählen Sie dann Ihren Cluster und Ihre Datenbank aus den Dropdown-Menüs für "Clustername" und "Datenbankname" aus. Wählen Sie für den "Sammlungsnamen" die Option "Neue Sammlung erstellen", woraufhin ein zusätzliches Textfeld erscheint. Geben Sie in dieses neue Feld user_custom_data ein und klicken Sie auf Erstellen. Auf diese Weise werden unsere benutzerdefinierten Daten in einer von unseren Kundendaten getrennten Sammlung gespeichert.

Geben Sie in das Feld "Benutzer-ID" Folgendes ein user_id. Dies dient als Fremdschlüssel für den Benutzer, dem die Daten zugeordnet sind. Obwohl wir in Teil 3 erwähnt haben, dass wir dies nicht tun sollten, ist dies einer der Fälle, in denen es sinnvoll ist, so etwas wie einen Fremdschlüssel für eine relationale Datenbank zu verwenden. Die Tabelle, in der die Benutzerdaten gespeichert sind, wird vollständig verwaltet, so dass wir keinen direkten Zugriff darauf haben. Das bedeutet, dass wir diese Daten nicht in den Benutzerdatensatz einbetten können und auch die Benutzeranmeldeinformationen nicht zusammen mit den Benutzerdaten speichern wollen.

Wenn das alles erledigt ist, klicken Sie auf Entwurf speichern und dann Entwurf prüfen & bereitstellen um die neuen Einstellungen zu speichern.

Nach der Bereitstellung gehen Sie zurück zum Benutzer Registerkarte. Wir möchten unseren neuen Benutzer als Administrator kennzeichnen, also lassen Sie uns diese benutzerdefinierten Benutzerdaten erstellen. Wir benötigen die ID des soeben erstellten Benutzers, also kopieren Sie diese ID für den Benutzer. Gehen Sie dann zurück zu Datendienste in der oberen Navigationsleiste und gehen Sie zu Sammlungen durchsuchen.

Wir müssen eine neue Sammlung anlegen, also fahren Sie mit dem Mauszeiger über den restaurant_pos_demo Datenbanknamen, und ein + erscheint rechts neben dem Text. Klicken Sie darauf, und geben Sie dann user_custom_data als Name der Sammlung ein. Klicken Sie nun auf Erstellen um eine leere Sammlung zu erstellen. Sobald diese erstellt ist, klicken Sie auf Dokument einfügen, wechseln Sie in die {} Ansicht und fügen Sie das folgende JSON-Dokument ein.

{
 "user_id": "<user-id-we-just-copied>",
 "admin":true
}

Wenn wir zu dem Code kommen, mit dem wir uns innerhalb unserer Anwendung anmelden, wird das admin dem Benutzer hinzugefügt, wenn es zurückgegeben wird. Sie können diesem Dokument auch beliebige weitere Informationen hinzufügen, die Sie in Ihrer Anwendung verfolgen möchten. Für unser Tutorial benötigen wir ein boolesches admin Flagge.

Sicherheit der Abfrage

Wir werden uns einen weiteren Abschnitt ansehen, während wir uns in der Atlas-Web-UI befinden. Eine Funktion, die unser administratives Backend für den Lehrgang verwendet, ist die Abfrage der Datenbank direkt von unserer clientseitigen Anwendung aus. In vielen Anwendungen, wie z.B. der Kundenseite unseres Tutorials, haben wir eine Backend-API, die auf unsere Daten zugreift. Atlas ermöglicht uns die Abfrage der Datenbank vom Browser aus durch eine Kombination aus Benutzerauthentifizierung, die wir gerade eingerichtet haben, und regelbasierten Datenzugriffskontrollen.

Klicken Sie rüber zu Regeln Auf dem Bildschirm "App Services" unter "Data Access" gelangen Sie zum Bildschirm "Rules", wo wir den Zugriff authentifizierter Benutzer steuern können. Im Moment führt unsere Anwendung keine Berechtigungsprüfung durch, aber das Hinzufügen ist nur ein paar Klicks entfernt.

Atlas App Rules configurationAtlas App Rules configration

Wir möchten sicherstellen, dass jeder Benutzer, der darauf zugreift, ein Administrator ist, da nur Administratoren auf diese Daten zugreifen dürfen. Für unsere Anwendung wollen wir nur denjenigen den Zugriff erlauben, die das admin Flag in ihrem Konto auf true gesetzt ist (sehen Sie, warum wir das vorhin schon eingerichtet haben?). Sie können Einschränkungen für die gesamte Datenbank oder pro Schema vornehmen. Da wir nur unserem Admin-Backend den direkten Zugriff auf die Datenbank erlauben, können wir diese Regeln der Datenbank selbst hinzufügen. Klicken Sie auf dem Bildschirm Regeln auf Standardrollen und Filter direkt über dem Datenbanknamen.

Wir können einige voreingestellte Rollen einrichten, wie z. B. alle verweigern oder alle zulassen. Wir wollen eine Regel erstellen, die unsere benutzerdefinierten Daten verwendet, also gehen Sie nach unten und klicken Sie auf Überspringen (von vorne beginnen).

New Atlas App dialogAdmin-Write rule config

Wir müssen unserer Rolle einen Namen geben, also nennen wir sie "admin-write". Dann müssen wir die Regeln festlegen, wann unsere Rolle gelten soll. Da wir uns Sorgen um den Zugriff auf Daten machen, wenn wir ein Administrator sind, können wir eine einfache Regel aufstellen, die sicherstellt, dass der Benutzer ein benutzerdefiniertes Datenattribut namens admin hat und dass es gesetzt ist auf true. Kopieren Sie den folgenden JSON-Block und fügen Sie ihn in den Editor ein.

{
    "%%user.custom_data.admin": true
}

%%user weist das Regelsystem an, den authentifizierten Benutzer zu überprüfen. Wenn wir uns authentifizieren, werden die in user_custom_data gespeicherten Informationen an den zurückgegebenen Benutzer angehängt und der custom_data Eigenschaft zugewiesen. Sie können eine beliebige Anzahl von Regeln hinzufügen, um dies so granular zu gestalten, wie Sie es in einer tatsächlichen Anwendung wünschen.

Darunter können wir die Dokumentberechtigungen festlegen. Da wir ein Admin-Benutzer sind, wählen Sie "Einfügen", "Löschen" und "Suchen", wodurch jeder Admin-Benutzer vollen Zugriff auf alle Dokumente in jeder Sammlung erhält. Schließlich haben wir noch die Feldberechtigungen. Sie können die Zugriffsregeln für eine Sammlung bis hin zu einer bestimmten Datei festlegen. Im Moment wählen Sie "Alle Felder lesen und schreiben".

Diese beiden Einstellungen sind vor allem dann nützlich, wenn Sie z. B. alle schreibgeschützten Ansichten auf bestimmte Benutzerrollen beschränken oder Felder von Rollen einschränken möchten, die nur einen gewissen Zugriff auf Informationen haben. Diese Regeln können in Verbindung mit umfassenderen Filterregeln verwendet werden, die einschränken, welche Daten überhaupt von einer Abfrage zurückgegeben werden können.

Speichern Sie alle diese Einstellungen, überprüfen Sie die neuen Zugriffskontrollen und stellen Sie sie bereit.

Als Letztes müssen wir unserer Anwendung mitteilen, mit welcher Atlas-App sie kommunizieren soll. Auf der Homepage der Atlas-App, die wir verwenden, befindet sich oben eine App-ID. Kopieren Sie diese nach unten und geben Sie sie in die .env Datei für die Webanwendung unter VITE_REALM_ID.

App ID locationApp ID location

Können wir uns schon anmelden?

Ja!

Gehen Sie zu http://localhost:5173/login und melden Sie sich mit der E-Mail-Adresse und dem Passwort an, die Sie dem Benutzer in Atlas zugewiesen haben. Sie sollten einen Bildschirm mit dem Inventar und der Möglichkeit, neue Gerichte hinzuzufügen, sehen. Wenn Sie dies sehen, sind Sie authentifiziert!

Tutorial Admin AreaTutorial Admin Area

MongoDB Atlas verfügt über ein Browser-SDK, mit dem wir unseren Cluster und unsere Atlas-Anwendung kontaktieren können. Wir müssen eine E-Mail-Adresse und ein Kennwort für unsere Anwendung eingeben und diese an die Authentifizierungsaufrufe des SDK übergeben.

import { MongoDBRealmError } from 'realm-web';
import { ref } from 'vue'
import { useRouter } from 'vue-router';
import { authenticationStore } from '../stores/authenticationStore';

const router = useRouter();
const username = ref('')
const password = ref('')
const authStore = authenticationStore()

const login = async () => {
    try {
        await authStore.login(username.value, password.value)
        router.push({ name: 'inventory.home' });
    } catch (error) {
        if (error instanceof MongoDBRealmError) {
            console.log(error.errorCode)
        }
    }
}

Der VueJS-Code ist relativ minimal. Unsere Login.vue-Komponentehaben wir einen Authentication Store eingebunden, der wie unser Einkaufswagen ein Wrapper ist, um die Weitergabe von eingeloggten Benutzerinformationen zu erleichtern. Dieser Store wird das SDK zur Anmeldung verwenden. Auf dieser Seite müssen wir nur darauf achten, dass der Benutzer sich über das Formular anmeldet und authStore.login() mit dem Benutzernamen und dem Passwort aufrufen.

import { defineStore } from 'pinia'
import * as Realm from 'realm-web'

const realmApp = new Realm.App({id: import.meta.env.VITE_REALM_ID})

export const authenticationStore = defineStore('authenticationStore', {
    state: () => {
        return {
            token: null,
            user: null,
        }
    },
    actions: {
        async login(username, password) {
            const creds = Realm.Credentials.emailPassword(username, password);
            this.user = await realmApp.logIn(creds)
            return this.user
        },
        setToken(token: string) {
            this.token = token
        },
        logout() {
            this.token = null
        }
    }
})

Der Authentifizierungsspeicher ist nicht viel mehr als ein Wrapper für das MongoDB SDK und einige Orte, um Benutzerinformationen zu speichern. Wir erstellen einen Store mit Pinia und erstellen ein neues Realm.App() Objekt mit einem Link zu unserer App ID, die wir in unserer .env Datei hinzugefügt haben. Innerhalb unseres authenticationStore Objekts befindet sich eine login() Methode namens Realm.Credentials.emailPassword(). Diese generiert einen Satz von Benutzerdaten, die wir zur Authentifizierung an das App-Objekt übergeben können. Wenn der Aufruf von realmApp.login() erfolgreich ist, erhalten wir einen Benutzer zurück. Wir speichern diesen Benutzer ab und können ihn jederzeit aus dem Speicher abrufen.

Von diesem Zeitpunkt an gilt unser Benutzer als authentifiziert. Jederzeit können wir prüfen authenticationStore.user überprüfen, und wenn eine vorhanden ist, sind wir authentifiziert. Da wir uns über das SDK bei Atlas angemeldet haben, können wir nun auch direkt über das Frontend auf die Datenbank zugreifen. Wir tun dies über einen Datenbank-Speicher. Dieser Speicher stellt lediglich eine Verbindung zu unserem MongoDB-Cluster her und verwendet die Anmeldedaten des angemeldeten Benutzers.

Dies ist sehr leistungsfähig, da wir Datenabfragen direkt im Browser durchführen können, anstatt uns auf unsere Backend-API zu verlassen. Mit den Regeln, die wir in der Atlas App-Konfiguration eingerichtet haben, können wir den Zugriff auf diese Daten auf Admin-Nutzer beschränken. Wenn wir den gesamten MongoDB-Code in unserer Backend-API wegwerfen wollten, könnten wir zusätzliche Regeln und Filter hinzufügen, damit die Benutzer nur die Daten sehen, auf die sie zugreifen können. Dies ist eine großartige Möglichkeit, eine Anwendung schnell zu skizzieren.

import { defineStore } from 'pinia'
import { authenticationStore } from './authenticationStore'

const authStore = authenticationStore()
const dataSource = import.meta.env.VITE_MONGODB_DATA_SOURCE
const databaseName = import.meta.env.VITE_MONGODB_DATABASE

export const mongodbStore = defineStore('mongodbStore', {
    state: () => {
        return {
            restaurantDb: authStore.user.mongoClient(dataSource).db(databaseName),
        }
    },
    actions: {
        getInventoryCollection() {
            return this.restaurantDb.collection('inventory')
        }
    }
})

Der Datenbankspeicher ist sehr minimal. Wir vereinfachen das Ziehen des Datenbankobjekts und der Sammlung aus der Realm-Verbindung, die wir im Authentication Store eingerichtet haben. Wir können dann die Datenbank von unserem VueJS-Code aus abfragen, wie bei der Inventar Komponente:

import { ref } from 'vue';
import { mongodbStore } from '../stores/mongodbStore';

const dbStore = mongodbStore()
let inventory = ref(Array());

async function getInventory() {
    const dishes = await dbStore.getInventoryCollection().find()
    inventory.value = Array()
    dishes.forEach(dish => {
        if (dish.name) {
            inventory.value.push(dish)
        }
    })
}

In unserer VueJS-Komponente ziehen wir den Datenbank-Speicher als mongodbStore. Wir können dann die MongoDB SDK-Syntax verwenden, um Dokumente zu finden, die wir verwenden können. Da wir alle Dokumente in der Inventory Collection haben wollen, können wir mit dbStore.getInventoryCollection().find() alle Dokumente zurückgeben, auf die wir Zugriff haben. Diese können wir dann in ein VueJS ref() Objekt übertragen, um sie auf der Seite anzuzeigen.

Ein wesentlicher Teil dieser Sequenz ist "wir haben Zugriff auf". Die Seite "Regeln" in der Atlas-App kann verwendet werden, um einzuschränken, welche Dokumente wir sehen können. Es ist zum Beispiel üblich, ein Dokument mit einem Benutzer zu verknüpfen, wie einem Autor (oder, in unserem Fall, der Person, die eine Bestellung aufgegeben hat). Sie können einen Filter einrichten, der nur die Bestellungen dieses Benutzers zurückgibt, selbst wenn er einen Aufruf an find() um alles zurückzugeben. Die Einschränkungen und Filter, die im Abschnitt Regeln der Atlas-App eingerichtet werden, ergänzen jede vom Browser durchgeführte Abfrage.

Schlussfolgerung

Atlas Apps kann dazu beitragen, einen Teil der Entwicklungszeit von Anwendungen durch Dinge wie Benutzerauthentifizierung und Abfragezugriff drastisch zu reduzieren. Wir können viele Funktionen komplett überspringen, z. B. die Möglichkeit, Funktionen auf einer serverlosen Plattform zu veröffentlichen oder ein API-Gateway zu aktivieren, um eine Microservice-Architektur für Ihren Browser oder Ihre mobile Anwendung zu erstellen. Es gibt sogar Datenreplikationssysteme, die Offline- und Datenabgleichsfunktionen für Anwendungen bieten.

Jetzt, wo wir angemeldet sind, müssen wir uns noch einen weiteren Punkt ansehen. Woher wissen wir, wenn ein Benutzer ein Problem hat? Wir werden uns den Bildschirm "Admin Orders" ansehen und wie wir Vonage In-App Messaging nutzen können, um Benachrichtigungen im Browser zu erhalten, dass ein Nutzer eine Meeting-Anfrage gestellt hat, und wie wir die Meetings API nutzen, um dem Restaurant Video-Hosting-Funktionen zu geben, die dem Kunden nicht zur Verfügung stehen.

Share:

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

Chris ist Staff PHP Developer Advocate und Leiter der Server SDK Initiative. Er programmiert seit mehr als 15 Jahren in verschiedenen Sprachen und Projekttypen, von Kundenprojekten bis hin zu Big-Data-Großsystemen. Er lebt in Ohio, verbringt seine Zeit mit seiner Familie und spielt Video- und TTRPG-Spiele.