Inhaltsverzeichnis
Was sind als nächstes.js und Appwrite und warum brauchen wir sie?
Weiter.js
Appwrite
Einführung in die Multi-Mieter-SaaS-Autorisierung
Bedeutung der Mieterisolation und der körnigen Zugangskontrolle
Was ist die Erlaubnis und wie hoch sind ihre Vorteile?
Systemarchitektur
Backend -Implementierung mit Genehmigung
1. Einrichten der Genehmigung
2. Installieren von Abhängigkeiten
3. Einrichten von Appwrite
4. Erstellen Sie Dateistruktur und Dateien
Reason for creating an extensive backend service using Appwrite
Abschluss
Heim Web-Frontend js-Tutorial Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Apr 11, 2025 am 08:23 AM

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Ich habe eine funktionale SaaS-Anwendung mit mehreren Mandanten (eine EdTech-App) mit Ihrem täglichen Tech-Tool erstellt und Sie können dasselbe tun.

Was ist eine SaaS-Anwendung mit mehreren Mietern?

Mit Multi-Tenant-SaaS-Anwendungen können Sie mehrere Kunden aus einer einzelnen Codebasis bedienen. Dazu müssen Sie jedoch einen sicheren und mieterspezifischen Zugang verwalten, und dies kann eine Herausforderung sein, wenn Sie manuell durchgeführt werden. Deshalb habe ich mich für die Nutzung der Genehmigung entschieden, ein modernes Autorisierungstool, das diesen Prozess vereinfacht.

In diesem Artikel zeige ich Ihnen, wie Sie die Autorisierung für Ihre SaaS-Anwendungen mithilfe der Genehmigung vereinfachen, mit einem Schritt-für-Schritt-Beispiel für den Aufbau einer Demo-App mit Mieter-Isolation und rollenbasiertem Zugriffskontroll (RBAC) mit Next.js und Appwrite.

Was sind als nächstes.js und Appwrite und warum brauchen wir sie?

Weiter.js

Next.js ist ein auf React-basiertes Framework, das Server-Side-Rendering (SSR), SSG (SSG), API-Routen und Leistungsoptimierungen für die statische Site ermöglicht.

Für dieses Projekt habe ich Next.js verwendet, weil:

  • Es ermöglicht die Vorrenderung von Seiten, was die Leistung und die SEO verbessert.
  • Das integrierte Routing erleichtert die Verwaltung von Seitenübergängen und dynamischen Inhalten.
  • Es wird einfach in Backend -Dienste wie AppWrite und erzulassen.io zur Authentifizierung und Autorisierung integriert.

Appwrite

AppWrite ist eine BAAS-Plattform (Backend-As-a-Service), die Benutzerauthentifizierung, Datenbanken, Speicher und serverlose Funktionen bietet. Durch die Verwendung eines Dienstes wie AppWrite müssen Sie ein Backend von Grund auf erstellen, sodass Sie sich auf die Frontend -Entwicklung konzentrieren können und gleichzeitig Zugriff auf Backend -Funktionen haben.

Für dieses Projekt habe ich Appwrite verwendet:

  • Um Benutzerregistrierung, Anmeldung und Sitzungsverwaltung zu behandeln.
  • Bereitstellung einer strukturierten NOSQL-Datenbank zum Speichern von mieterspezifischen Daten.

Durch die Verwendung von Next.js und AppWrite zusammen ermöglichte ich eine skalierbare, leistungsstarke SaaS-App mit mehreren Mandanten und hält gleichzeitig den Entwicklungsprozess effizient.

Einführung in die Multi-Mieter-SaaS-Autorisierung

Eine SaaS-App mit mehreren Tenanten ist eine Software, die mehreren Benutzern oder Benutzergruppen dient, die als Mieter bezeichnet werden und eine einzige Softwareinstanz der Anwendung verwendet werden.

Es bedeutet, dass in einer SaaS-Architektur mit mehreren Mietern mehrere Kunden (Mieter) dieselbe Anwendungsinfrastruktur teilen oder dieselbe Anwendung verwenden, aber die Datenisolierung beibehalten.

Ein praktisches Beispiel dafür ist ein Projektmanagement -Tool wie Trello.

  • Es handelt sich um eine einzige Infrastruktur, die auf gemeinsam genutzten Servern ausgeführt wird und die gleiche Codebasis für alle Benutzer enthält.
  • Jedes Unternehmen, das Trello (z. B. Unternehmen A und Firma B) verwendet, ist ein Mieter.
  • Es isoliert Daten:
    • Mitarbeiter des Unternehmens A können ihre Projekte, Aufgaben und Vorstände nur sehen.
    • Mitarbeiter des Unternehmens B können keine Daten von Unternehmen A zugreifen oder sie ansehen und umgekehrt.

Dies stellt sicher, dass die Daten und Aktivitäten jedes Mieters, während die Ressourcen geteilt werden, privat und sicher sind.

In einer Multi-Mieter-Anwendung haben einige Benutzer selbst innerhalb eines Mieters einen höheren Zugriff auf einige Informationen, während einige Mitglieder auf bestimmte Ressourcen beschränkt sind.

Genehmigung in solchen Bewerbungen muss:

  • Stellen Sie sicher, dass Benutzer nicht auf Daten oder Ressourcen anderer Mieter oder Kunden zugreifen können. Dies nennt man isolierende Mieter.
  • Stellen Sie sicher, dass Benutzer innerhalb eines Mieters nur auf Ressourcen zugreifen können, die ihre Rollen ermöglichen, indem sie eine detaillierte Zugriffskontrolle ermöglichen.
  • Behandeln Sie mehr Benutzer, Mieter und Rollen, ohne die Leistung zu verlangsamen oder zu verschlechtern.

Bedeutung der Mieterisolation und der körnigen Zugangskontrolle

Die Isolation von Mietern hält die Daten sicher, indem sichergestellt wird, dass die Informationen jedes Kunden privat bleiben. Während die granulare Zugriffskontrolle sicherstellt, dass Benutzer innerhalb einer Organisation nur die Berechtigungen erhalten, die sie benötigen.

Die Implementierung der Autorisierung in Ihren SaaS -Apps kann komplex und schwierig sein, aber es muss nicht sein, wenn Sie über ein autorisierungsbedingtes Instrument wie Erlaubnis verfügen.

Was ist die Erlaubnis und wie hoch sind ihre Vorteile?

Die Genehmigung ist ein benutzerfreundliches Autorisierungs-Tool für die Verwaltung des Zugriffs in jeder Anwendung, einschließlich Multi-Mandanten-Apps. Mithilfe von generit.io in Ihrer Anwendung können Sie die Rollen in Ihrer Anwendung auf einfache Weise Rollen für die Zugriffskontrolle definieren und zuweisen. Neben dem Erstellen von Rollen innerhalb der Anwendung können Sie auch Bedingungen und Regeln auf der Grundlage von Benutzer- oder Ressourcenattributen hinzufügen, um anzugeben, was jeder Benutzer tun kann und was nicht.

Nachdem Sie nun das meiste wissen, was Sie über die Erlaubnis und ihre Vorteile wissen müssen, lassen Sie uns in das Hauptgeschäft eingehen.

Um die Leistung der Genehmigung zu demonstrieren, werden wir eine Multi-Mieter-EDTech SaaS-Plattform bauen.

Der Aufbau einer Edtech SaaS-Plattform beinhaltet mehrere Herausforderungen, darunter Benutzerauthentifizierung, rollenbasierte Access Control (RBAC) und Multi-Messen. Wir werden Next.js für das Frontend, Appwrite für Authentifizierung und Datenbankverwaltung und die Erlaubnis für die feinkörnige Genehmigung verwenden.

Tech -Stack -Übersicht

Technologypurposenext.jsfrontend FrameworkShadcn Tailwindcssui-Komponenten und StylingzustandState ManagementAppwriteAuthentication & BackendPermit.iorole-basierte Zugriffskontrolle

Systemarchitektur

Die Anwendung folgt einem Backend-First-Ansatz:

  1. Backend (Node.js Express)
    • Behandelt API -Anfragen und Geschäftslogik.
    • Verwendet AppWrite für Authentifizierung und Datenbankverwaltung.
    • Implementierung der Erlaubnis zur Genehmigung, Definieren von Rollen und Berechtigungen.
    • Stellen Sie sicher, dass jede Anfrage vor dem Datenzugriff validiert wird.
  2. Frontend (next.js)
    • Stellt eine Verbindung zum Backend her, um Daten sicher abzurufen.
    • Verwendet eine rollenbasierte UI-Rendering, was bedeutet, dass Benutzer nur sehen, auf was sie zugegriffen werden.
    • Beschränken Sie Aktionen (z. B. Erstellen von Zuordnungen) basierend auf Berechtigungen.

Durch die Durchsetzung der Autorisierung auf API -Ebene stellen wir sicher, dass Benutzer keine Beschränkungen umgehen können, selbst wenn sie die Frontend manipulieren.

Am Ende dieses Handbuchs haben Sie eine voll funktionsfähige Multi-Tenant-Edtech SaaS-App, in der:

  • Administratoren können Schüler hinzufügen und anzeigen.
  • Lehrer können Schüler hinzufügen und anzeigen und Aufgaben erstellen.
  • Die Schüler können ihre zugewiesenen Kursarbeit nur anzeigen.

Dieser Artikel enthält eine Schritt-für-Schritt-Aufschlüsselung darüber, wie ich die Genehmigung für die Erstellung dieses Projekts implementiert habe. Folgen und bauen Sie Ihre.

Backend -Implementierung mit Genehmigung

Um eine rollenbasierte Zugriffskontrolle (RBAC) und die Isolation von Mietern durchzusetzen, müssen wir:

  1. Richten und definieren Sie Rollen, Mieter und Richtlinien.
  2. Integrieren Sie die Erlaubnis in das Backend (Node.js Express).
  3. Schützen Sie API -Routen mithilfe von Middleware, die die Berechtigungen überprüft, bevor Anforderungen zuzulassen.

Lass uns Schritt für Schritt gehen.

1. Einrichten der Genehmigung

Vor dem Schreiben eines Codes müssen Sie

  • Erstellen Sie ein Konto für die Genehmigung.
Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Sie erhalten das Onboarding, aber sobald Sie Ihren Organisationsnamen eingeben, können Sie einfach das Setup überspringen.

  • Erstellen Sie eine Ressource und Aktionen

Navigieren Sie zum Richtlinienabschnitt, in dem Sie eine Ressource und Aktionen erstellen, die Sie in dieser Ressource ausführen können.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Sobald Sie mit dem Erstellen Ihrer Ressourcen fertig sind, sollte dies so aussehen:

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)
  • Eine Rolle schaffen

Navigieren Sie nach dem Erstellen der Ressourcen mit der Registerkarte Rollen zur Seite der Rollen. Sie werden sehen, dass einige Rollen automatisch zugewiesen wurden.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Löschen Sie diese Rollen und erstellen Sie neue Rollen. Jede Rolle ist mit spezifischen Regeln zugeordnet, was ein Benutzer kann und was nicht. Erstellen Sie zuerst die Administratorrolle, da sie später als Baustein für die RBAC -Bedingungen dienen wird. Klicken Sie oben auf die Schaltfläche Rollen hinzufügen und erstellen Sie die Rollen.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Wenn Sie mit dem Erstellen Ihrer Rollen fertig sind, sollte dies so aussehen:

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Großartig!

Nachdem Sie Ihre Ressourcen und Rollen erstellt haben, können Sie jetzt Berechtigungen im Richtlinieneditor konfigurieren.

  • Konfigurieren von Berechtigungen im Richtlinieneditor

Kehren Sie zum Richtlinieneditor zurück und so werden die Rollen jetzt aussehen, wobei jede einzelne Ressource definiert und die Aktionen, die Sie auswählen können. Sie sind jetzt bereit, den Rollen Berechtigungen zu erteilen, um die ausgewählten Aktionen auf der Ressource auszuführen.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Wenn Sie fertig sind, um die Aktionen für jede Rolle auszuwählen, klicken Sie unten rechts auf die Schaltfläche "Änderungen speichern".

  • API -Schlüssel kopieren

Um den Cloud -PDP der Genehmigung zu verwenden, benötigen Sie den API -Schlüssel Ihrer aktuellen Umgebung. Für dieses Projekt werden Sie den Entwicklungsumfeldschlüssel verwenden. Fahren Sie mit den Einstellungen fort und klicken Sie auf API -Schlüssel, scrollen Sie nach unten zu Umgebungs -API -Schlüssel, klicken Sie auf "Taste" und kopieren Sie es.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Nachdem Sie Ihr Erlaubnis -Dashboard eingerichtet haben, können Sie jetzt zu Ihrem Backend übergehen.

2. Installieren von Abhängigkeiten

Um loszulegen, müssen Sie Node.js auf Ihrem Computer installieren lassen. Befolgen Sie die folgenden Schritte, nachdem sichergestellt wird, dass Node.js in Ihrem System installiert ist:

  • Erstellen Sie mit den folgenden Befehlen ein neues Projekt:
 Mkdir Backend
CD -Backendnpm init -y
Nach dem Login kopieren
  • Installieren Sie dann die folgenden Pakete:
 NPM Installieren Sie Express dotenv generell cors Appwwrite axios jsonWeBtoken
Nach dem Login kopieren
  • Konfigurieren Sie die Genehmigung in Express. Speichern Sie in Ihrer .EnV -Datei Ihre API -Taste:
 Erlauben_api_key = your-permit-key-you-copied-earlier
Nach dem Login kopieren

3. Einrichten von Appwrite

  • Gehen Sie zu AppWrite und erstellen Sie ein neues Projekt, indem Sie einen Projektnamen eingeben und eine Region auswählen. Beachten Sie Ihre Projekt -ID und API -Endpunkt. Das werden Sie als Werte in Ihrer .env -Datei eingeben. Ihre Env -Datei sollte so aussehen:
 Erlauben_api_key = your-permit-key-you-copied-earlier
Appwrite_endpoint = https: //cloud.appwrite.io/v1
Appwrite_project_id = your-project-id
Nach dem Login kopieren
  • Fahren Sie nun zu Datenbanken fort, um Ihre Datenbank zu erstellen, und kopieren Sie Ihre Datenbank -ID, um sie in Ihre Env -Datei einzufügen.
Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Ihre Env -Datei sollte jetzt so aussehen:

 Erlauben_api_key = your-permit-key-you-copied-earlier
Appwrite_endpoint = https: //cloud.appwrite.io/v1
Appwrite_project_id = your-project-id
Appwrite_database_id = your-database-id
Nach dem Login kopieren

Erstellen Sie nun die folgenden Sammlungen in der AppWrite -Datenbank mit den folgenden Attributen:

  • Profilsammlung
Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)
  • Studentensammlung
Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)
  • Aufgaben Sammlung
Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Wie Ihre Env -Datei an diesem Punkt aussehen sollte:

 Erlauben_api_key = your-permit-key-you-copied-earlier
Erlauben_project_id = Copy-from-Dasboard
Erlauben_env_id = Copy-from-Dasboard
Appwrite_endpoint = https: //cloud.appwrite.io/v1
Appwrite_project_id = your-project-id
Appwrite_database_id = your-database-id
Appwrite_profile_collection_id = your-id
Appwrite_asssignments_collection_id = your-id
Appwrite_students_collection_id = your-id
Jwt_secret = generate-this-by-running // openssl rand -base64 16
Port = 8080
Nach dem Login kopieren

4. Erstellen Sie Dateistruktur und Dateien

Erstellen Sie nun einen SRC -Ordner im Root der Datei. Generieren Sie dann die Datei tsconfig.json im Root -Ordner und fügen Sie den folgenden Code in sie ein:

 <span>{
</span><span>"Compileroptions": {{
</span><span>"Ziel": "ES6",
</span><span>"Modul": "Commonjs",
</span><span>"Outdir": "./Dist",
</span><span>"EsmoduleInterop": true,
</span><span>"ForceconsistentcasinginfileNames": wahr,
</span><span>"streng": wahr,
</span><span>"SkipliBcheck": wahr,
</span><span>"ResolvejsonModule": Richtig,
</span><span>"BaseUrl": "./",
</span><span>"Pfade": {
</span><span>"@/*": ["src/*"]
</span><span>}
</span><span>},
</span><span>"Include": ["src/**/*"],
</span><span>"ausschließen": ["node_modules", "dist"]
</span><span>}</span>
Nach dem Login kopieren

Dieser tsconfig.json konfiguriert den TypeScript -Compiler, um ES6 zu zielen, CommonJS -Module zu verwenden und Dateien auf ./DIST auszugeben. Es erzwingt strenge Typ-Überprüfungen, ermöglicht die Auflösung des JSON-Moduls, legt Pfad-Aliase für SRC ein und schließt NODE_MODULES und DIST aus der Kompilierung aus.

Erstellen Sie im SRC -Ordner die folgenden Ordner: API, Konfiguration, Controller, Middleware, Modelle und Utils.

  • Utils -Ordner
    • Erstellen Sie nun eine neue Genehmigung.TS -Datei im Utils -Ordnerprojekt, um die Genehmigung mithilfe des folgenden Code zu initialisieren:
 <span>import {genehmigen} aus 'illyio';
</span><span>Import {erlaubte_api_key} aus '../config/environment';
</span><span>// Diese Zeile initialisiert die SDK und verbindet Ihre Node.js -App
</span><span>// In den PDP -Container von genannten.io, den Sie im vorherigen Schritt eingerichtet haben.
</span><span>const erlaubte = neue Erlaubnis ({{{
</span><span>// Ihre API -Schlüssel
</span> Token <span>: Erlaubnis_API_KEY, // Speichern Sie Ihren API -Schlüssel in .Env
</span><span>// In der Produktion müssen Sie möglicherweise diese URL ändern, um Ihre Bereitstellung zu entsprechen
</span> PDP <span>: 'https://cloudpdp.api.permit.io', // Standard -Genehmigung.io PDP -URL
</span><span>// Wenn Sie möchten, dass der SDK Protokolle abgibt, wenden Sie sich an:
</span> Protokoll <span>: {
</span> Level <span>: "Debugg",
</span><span>},
</span><span>// Der SDK gibt false zurück, wenn Sie einen Timeout- / Netzwerkfehler erhalten
</span><span>// Wenn Sie möchten, dass es stattdessen einen Fehler macht, und Sie damit umgehen lassen, wenden Sie sich an:
</span><span>// thryonError: wahr,
</span><span>});
</span>
<span>Ausfuhrverzugserlaubnis;</span>
Nach dem Login kopieren

Diese Datei initialisiert das SDK von Gen Dient für node.js und verbindet sie mit dem PDP -Container der Genehmigung mit einem in der Umgebung gespeicherten API -Schlüssel. Es konfiguriert die Protokollierung für das Debuggen und richtet die SDK so ein, dass Fehler lautlos verarbeitet werden, sofern sie nicht explizit konfiguriert werden, um sie zu werfen.

  • Erstellen Sie anschließend eine Datei namens ERRAGEHANDLER.TS und fügen Sie den folgenden Code ein:
 <span>// Versorgungsfunktionen (z. B. Fehlerbehandlung)
</span><span>importieren {request, antwort, nextFunction} aus 'Express';
</span>
<span>exportieren const erfehlerhandler = (ERR: Any, Req: Request, Res: Antwort, Weiter: NextFunction) => {
</span><span>console.Error ('error:', err.message || err);
</span> res <span>.status (err.status || 500) .json ({{{{
</span> Fehler <span>: err.message || 'Interner Serverfehler',
</span><span>});
</span><span>};</span>
Nach dem Login kopieren

Diese Datei definiert eine Express-Fehlerhandling-Middleware, die Fehler protokolliert und eine JSON-Antwort mit der Fehlermeldung und dem Statuscode sendet. Es wird standardmäßig mit einem 500 -Status -Code eingestuft, wenn kein spezifischer Status bereitgestellt wird.

  • Modelle Ordner
    • Erstellen Sie eine Datei namens Profil.TS und fügen Sie den folgenden Code ein:
 <span>Export -Schnittstellenprofil exportieren {
</span> Name <span>: String;
</span> E -Mail <span>: Zeichenfolge;
</span> Rolle <span>: 'Admin' | 'Lehrer' | 'Student';
</span> BenutzerID <span>: String;
</span><span>}</span>
Nach dem Login kopieren

Diese Datei definiert eine TypeScript -Profil -Schnittstelle mit Eigenschaften für Name, E -Mail, Rolle und BenutzerID, wobei die Rolle auf bestimmte Werte beschränkt ist: Administrator, Lehrer oder Schüler.

  • Datei zuweisen.ts Datei erstellen und fügen Sie den folgenden Code ein:
 <span>{Datenbank importieren, id} aus '../config/appwrite';
</span><span>Import {database_id, teliMents_collection_id} aus '../config/environment';
</span>
<span>Exportieren der Schnittstellenzuweisungen exportieren {
</span> Titel <span>: String;
</span> Betreff <span>: String;
</span> Klassenname <span>: String;
</span> Lehrer <span>: String;
</span> duedate <span>: String;
</span> Creatoremail <span>: String;
</span><span>}
</span>
<span>// Erstellen Sie eine neue Zuordnung
</span><span>Exportieren Sie die asynchronisierte Funktion createasSsignmentIndB (Daten: ordnungsdata) {
</span><span>Warten Sie warten auf database.createdocument (
</span><span>Datenbank_id,
</span><span>Zuweisungen_Collection_id,
</span><span>Id.unique (),
</span>   Daten
<span>);
</span><span>}
</span>
<span>// Alle Aufgaben abrufen
</span><span>exportieren
</span><span>const response = warte auf database.listdocuments (Database_id, telegments_collection_id);
</span><span>Rückgabeantwort.Dokumente;
</span><span>}</span>
Nach dem Login kopieren

Diese Datei bietet Funktionen für die Interaktion mit einer AppWrite -Datenbank zum Verwalten von Zuordnungen. Es definiert eine Zuweisungs -Schnittstelle und enthält Funktionen zum Erstellen einer neuen Zuordnung und zum Abholen aller Zuordnungen aus der Datenbank.

  • Erstellen Sie eine student.ts -Datei und fügen Sie den folgenden Code ein:
 <span>Import {Datenbank, ID, Erlaubnis, Rolle, Abfrage} aus '../config/appwrite';
</span><span>import {database_id, student_collection_id} aus '../config/environment';
</span>
<span>Export -Schnittstelle studentData {
</span> FirstName <span>: String;
</span> LastName <span>: String;
</span> Geschlecht <span>: 'Mädchen' | 'Junge' | 'Junge' | 'Mädchen';
</span> Klassenname <span>: String;
</span> Alter <span>: Zahl;
</span> Creatoremail <span>: String;
</span><span>}
</span>
<span>// Erstellen Sie einen neuen Schüler
</span><span>Exportieren Sie die asynchronisierende Funktion CreatestudentIndb (Daten: StudentData) {
</span><span>Warten Sie warten auf database.createdocument (
</span><span>Datenbank_id,
</span><span>Students_collection_id,
</span><span>Id.unique (),
</span> Daten <span>,
</span><span>[
</span> Erlaubnis <span>.
</span><span>]
</span><span>);
</span><span>}
</span>
<span>// Alle Schüler holen
</span><span>exportieren
</span><span>const response = warte auf database.listdocuments (Database_id, student_collection_id);
</span><span>Rückgabeantwort.Dokumente;
</span><span>}</span>
Nach dem Login kopieren

Diese Datei bietet Funktionen zum Verwalten von Studentendaten in einer AppWrite -Datenbank. Es definiert eine StudentData -Schnittstelle und enthält Funktionen, um einen neuen Schüler mit öffentlichen Lesemerkenntnissen zu erstellen und alle Schüler aus der Datenbank zu holen.

  • Middleware -Ordner
    • Erstellen Sie die Datei auth.ts und fügen Sie den folgenden Code ein:
 <span>importieren {request, antwort, nextFunction} aus 'Express';
</span><span>JWT von 'JsonWebtoken' importieren;
</span>
<span>// Anforderungsart so erweitern, um "Benutzer" einzuschließen.
</span><span>Interface AuthenticatedRequest erweitert die Anfrage {
</span> Benutzer <span>?: {
</span>  ID <span>: String;
</span>  Rolle <span>: String;
</span><span>};
</span><span>}
</span>
<span>const authmiddleware = (req: authenticatedRequest, Res: Antwort, Weiter: NextFunction): void => {
</span><span>const token = req.Headers.authorization? .Split ('') [1];
</span>
<span>if (! token) {
</span>  res <span>.Status (401) .json ({Fehler: 'Unauthorized. No Token bereitgestellt'});
</span><span>zurückkehren
</span><span>}
</span>
<span>versuchen {
</span><span>const decoded = jwt.verify (token, process.env.jwt_secret!) AS {id: String; Rolle: String};
</span>  req <span>.User = decodiert;
</span><span>nächste();
</span><span>} catch (error) {
</span>  res <span>.Status (403) .json ({Fehler: 'Ungültiges Token'});
</span><span>zurückkehren
</span><span>}
</span><span>};
</span>
<span>StandardauthMiddleware exportieren;</span>
Nach dem Login kopieren


Diese Datei definiert eine Express Middleware für JWT-basierte Authentifizierung. Es prüft ein gültiges Token im Anforderungsheader, überprüft es mithilfe eines geheimen Schlüssels und fügt die dekodierten Benutzerinformationen (ID und Rolle) an das Anforderungsobjekt an. Wenn das Token fehlt oder ungültig ist, gibt es eine geeignete Fehlerantwort zurück.

  • Erstellen Sie Erlaubnis. Und fügen Sie den folgenden Code ein:
 <span>Import -Genehmigung von '../utils/permit';
</span>
<span>exportieren const CheckUsertopmitstudents = async (E -Mail: String, Aktion: String, Ressource: String): Versprechen <boolean> => {
</boolean></span><span>versuchen {
</span><span>const erlaubte = wartete genehmigen. Check (E -Mail, Aktion, Ressource);
</span><span>console.log ("erlaubt", erlaubt);
</span><span>Rückgabe erlaubt;
</span><span>} catch (error) {
</span><span>console.Error ( <span>`Fehlersynchronisierung von Benutzer <span>$ {E -Mail},</span> um zu erlauben.io:`</span> , Fehler);
</span><span>false zurückgeben;
</span><span>}
</span><span>};
</span>
<span>Export const const CheckUsertoperMitSignment = Async (E -Mail: String, Aktion: String, Ressource: String): Versprechen <boolean> => {
</boolean></span><span>versuchen {
</span><span>const erlaubte = wartete genehmigen. Check (E -Mail, Aktion, Ressource);
</span><span>console.log ("erlaubt", erlaubt);
</span><span>Rückgabe erlaubt;
</span><span>} catch (error) {
</span><span>console.Error ( <span>`Fehlersynchronisierung von Benutzer <span>$ {E -Mail},</span> um zu erlauben.io:`</span> , Fehler);
</span><span>false zurückgeben;
</span><span>}
</span><span>};</span>
Nach dem Login kopieren

Diese Datei definiert Dienstprogrammfunktionen, CheckUsertopmitstudentents und CheckUsertoperMitSsignment, um die Erlaubnis der Benutzerberechtigungen für bestimmte Maßnahmen und Ressourcen zu überprüfen. Beide Funktionen verarbeiten Fehler anmutig, protokollieren Probleme und geben falsch zurück, wenn die Berechtigungsprüfung fehlschlägt. Sie werden verwendet, um die Genehmigung im Antrag durchzusetzen.

  • Controller -Ordner
    • Erstellen Sie die Datei auth.ts und fügen Sie den folgenden Code ein:
 <span>{Konto importieren, id} aus '../config/appwrite';
</span><span>{Anfrage, Antwort} aus 'Express' importieren;
</span><span>JWT von 'JsonWebtoken' importieren;
</span>
<span>const jwt_secret = process.env.jwt_secret as String; // Stellen Sie sicher, dass dies in Ihrer .env -Datei festgelegt ist
</span>
<span>// Anmeldesteuerung
</span><span>Export const Signup = async (Req: Anfrage, Res: Antwort) => {
</span><span>const {E -Mail, Passwort, Name} = req.body;
</span>
<span>if (! E -Mail ||! Passwort ||! Name) {
</span><span>return res.status (400) .json ({Fehler: 'Name, E -Mail und Passwort sind erforderlich.'});
</span><span>}
</span>
<span>versuchen {
</span><span>const user = act act account.create (id.unique (), mail, password, name);
</span><span>// JWT erzeugen
</span><span>const token = jwt.Sign ({E -Mail}, jwt_secret, {expiresin: '8H'});
</span>   Res <span>.cookie ('Token', Token, {
</span>    httponly <span>: wahr,
</span>    samesit <span>: 'streng',
</span>    sicher <span>: wahr,
</span><span>});
</span>
  Res <span>.Status (201) .json ({Erfolg: True, Benutzer, Token});
</span><span>} catch (Fehler: Any) {
</span><span>console.Error ('Anmeldefehler:', Fehler);
</span>  res <span>.Status (500) .json ({Erfolg: false, meldung: error.message});
</span><span>}
</span><span>};
</span>
<span>// Login -Controller
</span><span>Export const login = async (req: request, res: response) => {
</span><span>const {E -Mail, Passwort} = req.body;
</span>
<span>if (! E -Mail ||! Passwort) {
</span><span>return res.status (400) .json ({Fehler: 'E -Mail und Passwort sind erforderlich.'});
</span><span>}
</span>
<span>versuchen {
</span><span>const session = act act account.createEmailpasswordSession (E -Mail, Passwort);
</span>
<span>// JWT ohne Rolle erzeugen
</span><span>const token = jwt.sign (
</span><span>{userId: seseerid, E -Mail}, // keine Rolle enthalten
</span><span>Jwt_secret,
</span><span>{abgelaufen: '8H'}
</span><span>);
</span>
  Res <span>.cookie ('Token', Token, {
</span>   httponly <span>: wahr,
</span>   samesit <span>: 'streng',
</span>   sicher <span>: wahr,
</span><span>});
</span>
  Res <span>.Status (200) .json ({Erfolg: true, token, session});
</span><span>} catch (Fehler: Any) {
</span><span>console.Error ('Anmeldefehler:', Fehler);
</span>  res <span>.Status (401) .json ({Erfolg: false, meldung: error.message});
</span><span>}
</span><span>};
</span>
<span>// Logout -Controller
</span><span>exportieren const logout = async (req: request, res: response) => {
</span><span>versuchen {
</span><span>Warte Account.Deletesession ('aktuelle Sitzungs -ID');
</span>  res <span>.clearcookie ('token');
</span>  Res <span>.Status (200) .json ({Erfolg: true, message: 'erfolgreich angemeldet'});
</span><span>} catch (Fehler: Any) {
</span><span>console.Error ('logout error:', error);
</span>  res <span>.Status (500) .json ({Erfolg: false, meldung: error.message});
</span><span>}
</span><span>};</span>
Nach dem Login kopieren

Diese Datei definiert Authentifizierungscontroller für Anmeldung, Anmeldung und Anmeldung und integriert sich in AppWrite für die Benutzerverwaltung und JWT für die Sitzung. Die Anmeldungs- und Anmeldecontroller validieren Eingaben, erstellen Benutzersitzungen und generieren JWTs, während der Abmeldesteuerungs -Controller die Sitzung und das Token löscht. Alle Controller verarbeiten Fehler und geben entsprechende Antworten zurück.

  • Datei zuweisen.ts Datei erstellen und fügen Sie den folgenden Code ein:
 <span>{Anfrage, Antwort} aus 'Express' importieren;
</span><span>Import {CreateasSignmentIndB, ordnungsdata, fetchaDassignments aus} aus '../models/assignent';
</span><span>Import {CheckUsertopmitAssignment} aus '../middleware/permit';
</span>
<span>// Erstellen Sie eine neue Zuordnung
</span><span>Exportieren Sie die Asynchronisierungsfunktion CreateasSsignment (Requal: Request , Res: Antwort): Promise <void> {
</void></span><span>versuchen {
</span><span>const {title, Thema, Lehrer, Klassenname, duedate, CreateMail}: Auftragsdata = req.body;
</span>
<span>const isspermonded = Warte ucuSertopmitSsignment (CreateMail, "Create", "Zuweisungen");
</span><span>if (! isspermitted) {
</span>      res <span>.Status (403) .json ({Fehler: 'nicht autorisiert'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>const newAssignment = Warten Sie CreateasSignmentIndB ({{{{{{{{
</span>      Titel <span>,
</span>      Thema <span>,
</span>      Lehrer, Lehrer <span>,
</span>      Klassenname <span>,
</span>      Fälligkeitsdatum <span>,
</span>      Creatoremail
<span>});
</span>
<span>console.log ('Neue Zuordnung erstellt:', NewSsignment);
</span>
    Res <span>.Status (201) .Json (NewSsignment);
</span><span>} catch (error) {
</span><span>console.Error ('Erstellen von Fehlererstellung:', Fehler);
</span>    res <span>.Status (500) .json ({Fehler: (Fehler wie alle) .Message});
</span><span>} 
</span><span>}
</span>
<span>// Alle Aufgaben abrufen
</span><span>Exportieren Sie Async -Funktionen FetchaSsignments (Req: Request, Res: Antwort): Versprechen <void> {
</void></span><span>versuchen {
</span><span>const {E -Mail} = req.params;
</span> 
<span>const isspermitted = Warten Sie ucuSertopmitSsignment (E -Mail, "Read", "Aufgaben");
</span><span>if (! isspermitted) {
</span>      res <span>.Status (403) .json ({message: 'nicht autorisiert'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>const ordnungsgeräte = wartet fetchaDaNments aussomdb ();
</span>    Res <span>.Status (200) .Json (Zuweisungen);
</span><span>} catch (error) {
</span>    res <span>.Status (500) .json ({Fehler: (Fehler wie alle) .Message});
</span><span>}
</span><span>}</span>
Nach dem Login kopieren

Diese Datei definiert Controller für das Erstellen und Abholen von Zuweisungen, um sie in eine Datenbank zu integrieren und für Autorisierungsüberprüfungen zuzulassen. Der CreateasSsignment -Controller bestätigt Eingaben, überprüft die Berechtigungen und erstellt eine neue Zuordnung, während der FetchaDaD -Signment -Controller alle Zuordnungen nach Überprüfung des Zugriffs abruft. Beide Controller verarbeiten Fehler und geben entsprechende Antworten zurück.

  • Erstellen Sie eine student.ts -Datei und fügen Sie den folgenden Code ein:
 <span>importieren {
</span>  CreatestudentIndb <span>,
</span>  Fetchstudents <span>aus
</span>  Studentdata
<span>} aus '../models/student';
</span><span>{Anfrage, Antwort} aus 'Express' importieren;
</span><span>importieren {CheckUsertopmitstudents} aus '../middleware/permit';
</span>
<span>Exportieren Sie die asynchronisierende Funktion des Kreaturs (Req: Request, Res: Antwort): Versprechen <void> {
</void></span><span>versuchen {
</span><span>const {FirstName, Nachname, Geschlecht, Klassenname, Alter, CreateMail}: StudentData = req.body;
</span>
<span>if (! ['Mädchen', 'Junge']. Enthält (Geschlecht)) {
</span>      res <span>.Status (400) .json ({Fehler: 'Ungültiger Geschlechtstyp'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>const isspermitted = Warten Sie ucuSertopmitstudents (CreateMail, "erstellen", "Schüler");
</span><span>if (! isspermitted) {
</span>      res <span>.Status (403) .json ({message: 'nicht autorisiert'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>const newstudent = warte CreateStudentIndB ({{
</span>      FirstName <span>,
</span>      Lastname <span>,
</span>      Geschlecht <span>,
</span>      Klassenname <span>,
</span>      Alter <span>,
</span>      Creatoremail
<span>});
</span>    Res <span>.Status (201) .Json (NewStudent);
</span><span>} catch (error) {
</span>    res <span>.Status (500) .json ({Fehler: (Fehler wie alle) .Message});
</span><span>} 
</span><span>}
</span>
<span>// Alle Schüler holen
</span><span>Fetchstudents der asynchronischen Funktion exportieren (Requal: Request, Res: Antwort): Versprechen <void> {
</void></span><span>versuchen {
</span><span>const {E -Mail} = req.params;
</span>
<span>const isSermiteded = Warten Sie ucuSertopmitstudents (E -Mail, "lesen", "Studenten");
</span><span>if (! isspermitted) {
</span>      res <span>.Status (403) .json ({message: 'nicht autorisiert'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>const students = wartet fetchstudents fromdb ();
</span>    Res <span>.Status (200) .Json (Studenten);
</span><span>} catch (error) {
</span>    res <span>.Status (500) .json ({Fehler: (Fehler wie alle) .Message});
</span><span>}
</span><span>}</span>
Nach dem Login kopieren

Diese Datei definiert Controller für das Erstellen und Abholen von Schülern, die Integration in eine Datenbank und die Erlaubnis für Autorisierungsüberprüfungen. Der Createstudent Controller validiert Eingabe, überprüft die Berechtigungen und erstellt einen neuen Schüler, während der Fetchstudentents Controller alle Schüler nach Überprüfung des Zugriffs abruft. Beide Controller verarbeiten Fehler und geben entsprechende Antworten zurück.

  • Erstellen Sie ein Profil.ts -Datei und fügen Sie den folgenden Code ein:
 <span>{Profil} aus '@/models/profil' importieren;
</span><span>Axios aus 'Axios' importieren;
</span><span>Importieren {Datenbank, ID, Abfrage} aus '../config/appwrite';
</span><span>{Anfrage, Antwort, NextFunction, RequestHandler} aus 'Express';
</span><span>Import {erlaubte_api_key} aus '../config/environment';
</span>
<span>const profileId = process.env.appwrite_profile_collection_id als String; // Stellen Sie sicher, dass dies in .Env ist
</span><span>const DataBaseId = process.env.appwrite_database_id als String; // Stellen Sie sicher, dass dies in .Env ist
</span><span>const projectId = process.env.permit_project_id als String
</span><span>const EnvironmentID = process.env.permit_env_id als String
</span>
<span>const genehmigen_api_url = <span>`https://api.permit.io/v2/facts/ <span>$ {projectId}</span> / <span>$ {umweltid}</span> /user`</span> ;
</span><span>const erlaubte_auth_Header = {
</span> Autorisierung <span>: <span>`Bearer <span>$ {erlauben_api_key}</span> `</span> ,,
</span><span>"Inhaltstyp": "Anwendung/JSON",
</span><span>};
</span>
<span>// Profilcontroller erstellen
</span><span>Export const createProfile: RequestHandler = async (Req: Request, Res: Antwort, Weiter: Weitere Funktion): Versprechen <void> => {
</void></span><span>const {FirstName, Nachname, E -Mail, Rolle, userID} = req.body;
</span><span>console.log (req.body);
</span>
<span>if (! E -Mail ||! Rolle ||! UserId) {
</span>  res <span>.Status (400) .json ({Fehler: 'FirstName, LastName, E -Mail, Rolle und UserID sind erforderlich.'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>// Rolle validieren
</span><span>const erlaubte: profile ['rolle'] [] = ['admin', 'lehrer', 'schüler'];
</span><span>if (! erlaubtenroles.includes (Rolle)) {
</span>  res <span>.Status (400) .json ({Fehler: 'Ungültige Rolle. Erlaubte Rollen: admin, Lehrer, Schüler'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>versuchen {
</span><span>const newuser = wartet database.createdocument (
</span>   DatabaseId <span>,
</span>   ProfileId <span>,
</span><span>Id.unique (),
</span><span>{FirstName, LastName, E -Mail, Rolle, UserID}
</span><span>);
</span><span>// Schritt 2: Benutzer synchronisieren zu erlauben.io
</span><span>const essPayload = {
</span>   Schlüssel <span>: E -Mail,
</span>   E -Mail, E -Mail <span>,
</span>   First_Name <span>: FirstName,
</span>   Last_name <span>: LastName,
</span>   ROLE_Ssignments <span>: [{Rolle, Mieter: "Standard"}],
</span><span>};
</span>
<span>Lassen Sie die Erlaubnis;
</span><span>versuchen {
</span><span>const response = warte axios.post (erlaubte_api_url, generellload, {headers: erlauben_auth_header});
</span>   GenehmigungSResponse <span>= Antwort.Data;
</span><span>console.log ("Benutzer synchronisiert zu genehmigen.io:", detialResponse);
</span><span>} catch (erlaubterror) {
</span><span>if (axios.isaxiOseseserror (erlaubterror)) {
</span><span>console.Error ("nicht zu synchronisieren user to erlaubt.io:", erlaubterror.response?.
</span><span>} anders {
</span><span>console.Error ("Nicht synchronisieren, um zu erlauben.
</span><span>}
</span>   detliclesponse <span>= {error: "versäschte es nicht, mit erlaubten.io"} zu synchronisieren;
</span><span>}
</span>
<span>// Schritt 3: Beide Antworten zurückgeben
</span>  res <span>.status (201) .json ({{
</span>   Nachricht <span>: "Benutzerprofil erfolgreich erstellt",
</span>   Benutzer <span>: Newuser,
</span>   Genehmigung <span>: Genehmigungsponse,
</span><span>});
</span><span>zurückkehren;
</span><span>} catch (Fehler: Any) {
</span>  res <span>.Status (500) .json ({Erfolg: false, meldung: error.message});
</span><span>zurückkehren;
</span><span>}
</span><span>};
</span>
<span>// Profil per E -Mail abrufen
</span><span>Export const GetProfileByemail = Async (Req: Request, Res: Antwort, Weiter: Weitere Funktion): Versprechen <void> => {
</void></span><span>const {E -Mail} = req.params;
</span> 
<span>if (! E -Mail) {
</span>  res <span>.Status (400) .json ({Fehler: 'E -Mail ist erforderlich.'});
</span><span>zurückkehren;
</span><span>}
</span>
<span>versuchen {
</span><span>const profile = wartet database.listdocuments (
</span>   DatabaseId <span>,
</span>   ProfileId <span>,
</span><span>[Query.equal ("E -Mail", E -Mail)]]
</span><span>);
</span>
<span>if (profil.documents.length === 0) {
</span>   res <span>.Status (404) .json ({Fehler: 'Profil nicht gefunden'});
</span><span>zurückkehren;
</span><span>}
</span>
  Res <span>.Status (200) .json ({Erfolg: true, profil: profil.dokumente [0]});
</span><span>} catch (Fehler: Any) {
</span><span>console.Error ('Fehler beim Abrufen von Fetching:', Fehler);
</span>  res <span>.Status (500) .json ({Erfolg: false, meldung: error.message});
</span><span>}
</span><span>};</span>
Nach dem Login kopieren

Diese Datei definiert Controller zum Erstellen und Abholen von Benutzerprofilen, in der Integration in AppWrite für Datenbankvorgänge und ermöglichen die Rollensynchronisation. Der CreateProFile -Controller validiert Eingaben, erstellt ein Profil und synchronisiert den Benutzer, während der GetProfileByemail -Controller ein Profil per E -Mail abruft. Beide Controller verarbeiten Fehler und geben entsprechende Antworten zurück.

  • Konfigurationsordner
    • Erstellen Sie Appwrite.ts Datei und fügen Sie den folgenden Code ein:
 <span>Importieren {Client, Konto, Datenbanken, Speicher, ID, Berechtigung, Rolle, Abfrage} aus 'AppWrite';
</span><span>Import {Appwrite_endpoint, Appwrite_project_id, Appwrite_API_Key} aus './environment';
</span>
<span>// Initialisieren Sie den Appwrite -Client
</span><span>const client = neuer client ()
</span><span>.setendpoint (Appwrite_endpoint) // Appwrite Endpoint
</span><span>.setProject (appwrite_project_id); // Appwrite Project ID
</span>
<span>// API-Schlüssel hinzufügen, falls verfügbar (für serverseitige Operationen)
</span><span>if (appwrite_api_key) {
</span><span>(Client wie alle) .Config.Key = Appwrite_API_Key; // Problemumgehung, um den API -Schlüssel festzulegen
</span><span>}
</span>
<span>// Appwrite -Dienste initialisieren
</span><span>const Account = neues Konto (Client);
</span><span>const Database = neue Datenbanken (Client);
</span><span>const speicher = neuer Speicher (Client);
</span>
<span>// Appwrite -Client und -Dienste exportieren
</span><span>exportieren {client, Konto, Datenbank, Speicher, ID, Erlaubnis, Rolle, Abfrage};</span>
Nach dem Login kopieren

Diese Datei initialisiert und konfiguriert den AppWrite -Client mit dem Projektendpunkt, der ID und des optionalen API -Schlüssels. Außerdem werden AppWrite -Dienste wie Konto, Datenbanken und Speicher zusammen mit Dienstprogrammkonstanten wie ID, Erlaubnis, Rolle und Abfrage eingerichtet und exportiert.

  • Datei erstellen und fügen Sie den folgenden Code ein:
 <span>dotenv aus 'dotenv' importieren;
</span>dotenv <span>.config (); // Umgebungsvariablen von .env laden Umgebungsvariablen
</span>
<span>Export const Appwrite_endpoint = process.env.appwrite_endpoint || '';
</span><span>exportieren const erzulassen_api_key = process.env.permit_api_key || '';
</span><span>exportieren const genehmigen_project_id = process.env.permit_project_id || '';
</span><span>Export const erzulassen_env_id = process.env.permit_env_id || '';
</span><span>exportieren const Appwrite_project_id = process.env.appwrite_project_id || '';
</span><span>exportieren const database_id = process.env.appwrite_database_id || '';
</span><span>Export const students_collection_id = process.env.appwrite_students_collection_id || '';
</span><span>exportieren const zuweisungen_collection_id = process.env.appwrite_asssignments_collection_id || '';
</span>
<span>exportieren const profile_collection_id = process.env.appwrite_profile_collection_id || '';</span>
Nach dem Login kopieren

Diese Datei lädt Umgebungsvariablen aus einer .Env -Datei und exportiert sie als Konstanten für die Verwendung in der Anwendung, z. B. Appwrite- und Genehmigungskonfigurationen, Datenbank -IDs und Sammel -IDs. Standardwerte werden als Fallbacks bereitgestellt, wenn die Umgebungsvariablen nicht festgelegt sind.

  • API -Ordner
    • Erstellen Sie Student.ts und fügen Sie den folgenden Code ein:
 <span>Express aus "Express" importieren;
</span><span>importieren {createstudent, fetchstudents} aus '../controllers/student';
</span><span>AuthMiddleware aus '../middleware/Auth' importieren;
</span>
<span>const router = express.router ();
</span>
<span>// Endpunkte des Schülers definieren
</span>Router <span>.post ('/student', Authmiddleware, Createstudent); // Erstellen Sie einen neuen Schüler
</span>Router <span>.get ('/student/: mail', authmiddleware, fetchstudents); // Alle Schüler holen
</span><span>Standard -Router exportieren; // die Routerinstanz exportieren</span>
Nach dem Login kopieren

Diese Datei legt einen Express -Router mit Endpunkten für die Verwaltung von Studentendaten ein. Es enthält Routen zum Erstellen eines neuen Schülers und zum Abrufen von Schülern, die beide durch eine Authentifizierung Middleware (Authmiddleware) geschützt sind. Der Router wird dann zur Verwendung in der Anwendung exportiert.

  • Erstellen Sie die Datei auth.ts und fügen Sie den folgenden Code ein:
 <span>// src/routes/authroutes.ts
</span><span>Express aus "Express" importieren;
</span><span>Importieren {Anmeldung, Login, Logout} aus '../controllers/Auth';
</span>
<span>const router = express.router ();
</span>
<span>// authbezogene Endpunkte definieren
</span>Router <span>.post ('/Signup', (Req, Res, Next) => {// Anmelderoute
</span><span>Anmeldung (req, res) .then (() => {
</span><span>nächste();
</span><span>}). catch ((err) => {
</span><span>Weiter (arr);
</span><span>});
</span><span>});
</span>Router <span>.post ('/login', (req, res, next) => {// Anmelderoute
</span><span>Login (req, res) .then (() => {
</span><span>nächste();
</span><span>}). catch ((err) => {
</span><span>Weiter (arr);
</span><span>});
</span><span>});
</span>Router <span>.post ('/logout', logout); // Abmelderoute
</span><span>Standard -Router exportieren; // die Routerinstanz exportieren</span>
Nach dem Login kopieren

Diese Datei legt einen Express-Router mit Endpunkten für authentifizierungsbezogene Aktionen ein, einschließlich Benutzeranmeldung, Anmeldung und Abmelden. Die Anmeldungs- und Anmelderouten verarbeiten asynchrone Operationen mit Fehlerbehandlung, während die Abmelderoute unkompliziert ist. Der Router wird zur Verwendung in der Anwendung exportiert.

  • Datei zuweisen.ts Datei erstellen und fügen Sie den folgenden Code ein:
 <span>Express aus "Express" importieren
</span><span>importieren {createassignment, fetchaTsignments} aus "../controllers/assisignment" "
</span><span>Importieren Sie AuthMiddleware aus "../Middleware/Auth"
</span>
<span>const router = express.router ()
</span>
Router <span>.post ("/create", Authmiddleware, Createassignment)
</span>Router <span>.Get ("/: E -Mail", Authmiddleware, FetchaSsignments)
</span><span>Standard -Router exportieren</span>
Nach dem Login kopieren

Diese Datei legt einen Express -Router mit Endpunkten für die Verwaltung von Zuweisungen ein. Es enthält Routen zum Erstellen einer Zuordnung und zum Abrufen von Zuweisungen, die beide durch eine Authentifizierung Middleware (Authmiddleware) geschützt sind. Der Router wird zur Verwendung in der Anwendung exportiert.

  • Datei profile.ts erstellen und fügen Sie den folgenden Code ein:
 <span>Express aus "Express" importieren;
</span><span>Import {createProfile, getProfileByemail} aus '../controllers/profile';
</span><span>AuthMiddleware aus '../middleware/Auth' importieren;
</span>
<span>const router = express.router ();
</span>
<span>// Route zum Erstellen eines Profils
</span>Router <span>.post ('/profil', authmiddleware, createProfile);
</span>
<span>// Route zum Erhalten eines Profils per E -Mail
</span>Router <span>.get ('/profile/: mail', authmiddleware, getProfilebyemail);
</span><span>Standard -Router exportieren;</span>
Nach dem Login kopieren

This file sets up an Express router with endpoints for managing user profiles. It includes routes for creating a profile and fetching a profile by email, both protected by an authentication middleware (authMiddleware). The router is exported for use in the application.

  • Create index.ts file and paste the following code:
 <span>import express, { Request, Response } from 'express';
</span><span>import dotenv from 'dotenv';
</span><span>import cors from 'cors'; // CORS middleware
</span><span>import authRoutes from './auth'; // Import auth routes
</span><span>import profileRoutes from './profile';
</span><span>import studentRoutes from './student';
</span><span>import assignmentRoutes from './assignment';
</span><span>import { errorHandler } from '../utils/errorHandler'; // Custom error handler middleware
</span>
dotenv <span>.config(); // Load environment variables from .env file
</span>
<span>const app = express();
</span><span>const PORT = process.env.PORT || 8080;
</span>
<span>// Middleware
</span>app <span>.use(cors()); // Handle CORS
</span>app <span>.use(express.json()); /// Parse incoming JSON requests
</span>
<span>// Routes
</span>app <span>.use('/api/auth', authRoutes); // Authentication routes
</span>app <span>.use('/api', profileRoutes); // Profile routes mounted
</span>app <span>.use('/api', studentRoutes); // Student routes mounted
</span>app <span>.use('/api/assignments', assignmentRoutes); // Assignment routes mounted
</span>
<span>// Global Error Handling Middleware
</span>app <span>.use(errorHandler); // Handle errors globally
</span>
<span>// Default Route
</span>app <span>.get('/', (req: Request, res: Response) => {
</span> res <span>.send('Appwrite Express API');
</span><span>});
</span>
<span>// Start Server
</span>app <span>.listen(PORT, () => {
</span><span>console.log( <span>`Server is running on port <span>${PORT}</span> `</span> );
</span><span>});
</span><span>export default app;</span>
Nach dem Login kopieren

This file sets up an Express server, configuring middleware like CORS and JSON parsing, and mounts routes for authentication, profiles, students, and assignments. It includes a global error handler and a default route to confirm the server is running. The server listens on a specified port, logs its status, and exports the app instance for further use.

  • Finally, to run this project, change a part of package.json and install the following packages below so when you run npm run dev, it works.
    • Install packages:
 npm install concurrently ts-node nodemon --save-dev
Nach dem Login kopieren
  • By updating the scripts in the package.json, when you start the server, the typescript files are compiled to JavaScript in a new folder that is automatically created called dist
 "scripts": {
    "dev": "concurrently \"tsc --watch\" \"nodemon -q --watch src --ext ts --exec ts-node src/api/index.ts\"",
    "build": "tsc",
    "start": "node ./dist/api/index.js"
},
Nach dem Login kopieren

Now run npm run dev to start your server. When you see this message, it means that you have successfully implemented the backend.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)

Congratulations, your backend is ready for requests.

Now that our backend is set up, move on to frontend integration, where you'll:

  • Secure API requests from Next.js
  • Dynamically show/hide UI elements based on user permissions.

Reason for creating an extensive backend service using Appwrite

Appwrite is often described as a backend-as-a-service (BaaS) solution, meaning it provides ready-made backend functionality like authentication, database management, and storage without requiring developers to build a traditional backend.

However, for this project, I needed more flexibility and control over how data was processed, secured, and structured, which led me to create an extensive custom backend using Node.js and Express while still leveraging Appwrite's services.

Instead of relying solely on Appwrite's built-in API calls from the frontend, I designed a Node.js backend that acted as an intermediary between the frontend and Appwrite. This allowed me to:

  • Implement fine-grained access control with Permit.io before forwarding requests to Appwrite.
  • Structure API endpoints for multi-tenancy to ensure tenant-specific data isolation.
  • Create custom business logic, such as processing role-based actions before committing them to the Appwrite database.
  • Maintain a centralized API layer, making it easier to enforce security policies, log activities, and scale the application.

Appwrite provided the core authentication and database functionality of this application, but this additional backend layer enhanced security, flexibility, and maintainability, to ensure strict access control before any action reached Appwrite.

Abschluss

That's it for part one of this article series. In part 2, we'll handle the frontend integration by setting up API calls with authorization, initializing and installing necessary dependencies, writing out the component file codes, and handling state management & routes.

Das obige ist der detaillierte Inhalt vonErstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie erstelle ich meine eigenen JavaScript -Bibliotheken? Wie erstelle ich meine eigenen JavaScript -Bibliotheken? Mar 18, 2025 pm 03:12 PM

In Artikel werden JavaScript -Bibliotheken erstellt, veröffentlicht und aufrechterhalten und konzentriert sich auf Planung, Entwicklung, Testen, Dokumentation und Werbestrategien.

Wie optimiere ich den JavaScript -Code für die Leistung im Browser? Wie optimiere ich den JavaScript -Code für die Leistung im Browser? Mar 18, 2025 pm 03:14 PM

In dem Artikel werden Strategien zur Optimierung der JavaScript -Leistung in Browsern erörtert, wobei der Schwerpunkt auf die Reduzierung der Ausführungszeit und die Minimierung der Auswirkungen auf die Lastgeschwindigkeit der Seite wird.

Was soll ich tun, wenn ich auf den Codendruck auf Kleidungsstücke für Front-End-Thermalpapier-Quittungen stoße? Was soll ich tun, wenn ich auf den Codendruck auf Kleidungsstücke für Front-End-Thermalpapier-Quittungen stoße? Apr 04, 2025 pm 02:42 PM

Häufig gestellte Fragen und Lösungen für das Ticket-Ticket-Ticket-Ticket in Front-End im Front-End-Entwicklungsdruck ist der Ticketdruck eine häufige Voraussetzung. Viele Entwickler implementieren jedoch ...

Wie debugge ich den JavaScript -Code effektiv mithilfe von Browser -Entwickler -Tools? Wie debugge ich den JavaScript -Code effektiv mithilfe von Browser -Entwickler -Tools? Mar 18, 2025 pm 03:16 PM

In dem Artikel werden effektives JavaScript -Debuggen mithilfe von Browser -Entwickler -Tools, der Schwerpunkt auf dem Festlegen von Haltepunkten, der Konsole und der Analyse der Leistung erörtert.

Wie benutze ich Javas Sammlungsrahmen effektiv? Wie benutze ich Javas Sammlungsrahmen effektiv? Mar 13, 2025 pm 12:28 PM

In diesem Artikel wird der effektive Gebrauch des Sammlungsrahmens von Java untersucht. Es betont die Auswahl geeigneter Sammlungen (Liste, Set, Karte, Warteschlange) basierend auf Datenstruktur, Leistungsanforderungen und Thread -Sicherheit. Optimierung der Sammlungsnutzung durch effizientes Gebrauch

Wie verwende ich Quellkarten zum Debuggen, um den JavaScript -Code zu debuggen? Wie verwende ich Quellkarten zum Debuggen, um den JavaScript -Code zu debuggen? Mar 18, 2025 pm 03:17 PM

In dem Artikel wird erläutert, wie Quellkarten zum Debuggen von JavaScript verwendet werden, indem er auf den ursprünglichen Code zurückgegeben wird. Es wird erläutert, dass Quellenkarten aktiviert, Breakpoints eingestellt und Tools wie Chrome Devtools und WebPack verwendet werden.

Erste Schritte mit Chart.js: Kuchen-, Donut- und Bubble -Diagramme Erste Schritte mit Chart.js: Kuchen-, Donut- und Bubble -Diagramme Mar 15, 2025 am 09:19 AM

In diesem Tutorial wird erläutert, wie man mit Diagramm.js Kuchen-, Ring- und Bubble -Diagramme erstellt. Zuvor haben wir vier Chart -Arten von Charts gelernt. Erstellen Sie Kuchen- und Ringdiagramme Kreisdiagramme und Ringdiagramme sind ideal, um die Proportionen eines Ganzen anzuzeigen, das in verschiedene Teile unterteilt ist. Zum Beispiel kann ein Kreisdiagramm verwendet werden, um den Prozentsatz der männlichen Löwen, weiblichen Löwen und jungen Löwen in einer Safari oder den Prozentsatz der Stimmen zu zeigen, die verschiedene Kandidaten bei der Wahl erhalten. Kreisdiagramme eignen sich nur zum Vergleich einzelner Parameter oder Datensätze. Es ist zu beachten, dass das Kreisdiagramm keine Entitäten ohne Wert zeichnen kann, da der Winkel des Lüfters im Kreisdiagramm von der numerischen Größe des Datenpunkts abhängt. Dies bedeutet jede Entität ohne Anteil

TypeScript für Anfänger, Teil 2: Grundlegende Datentypen TypeScript für Anfänger, Teil 2: Grundlegende Datentypen Mar 19, 2025 am 09:10 AM

Sobald Sie das Typscript-Tutorial für Einstiegsklasse gemeistert haben, sollten Sie in der Lage sein, Ihren eigenen Code in eine IDE zu schreiben, die TypeScript unterstützt und in JavaScript zusammenfasst. Dieses Tutorial wird in verschiedenen Datentypen in TypeScript eingetaucht. JavaScript hat sieben Datentypen: NULL, UNDEFINED, BOOLEAN, NUMMER, STRING, SYMBOL (durch ES6 eingeführt) und Objekt. TypeScript definiert mehr Typen auf dieser Grundlage, und dieses Tutorial wird alle ausführlich behandelt. Null -Datentyp Wie JavaScript, null in TypeScript

See all articles