suchen
HeimWeb-Frontendjs-TutorialNgSysV.A Serious Svelte InfoSys: Firebase D/b-Regeln und Login

NgSysV.A Serious Svelte InfoSys: Firebase D/b rules and Login

Diese Beitragsserie ist auf NgateSystems.com indiziert. Dort finden Sie auch eine äußerst nützliche Stichwortsuchfunktion.

Letzte Bewertung: 24. November

1. Einführung

Als Sie mit Hilfe von Beitrag 2.3 Ihre erste Firestore-Datenbank erstellt haben, erinnern Sie sich vielleicht daran, dass Sie gefragt wurden, ob Sie „Produktions“- oder „Test“-Regeln anwenden möchten. Damals wurde vorgeschlagen, „Test“-Regeln auszuwählen. Wenn Sie zu diesem Zeitpunkt die Registerkarte „Regeln“ auf der Firestore-Seite in der Firebase-Konsole verwendet hätten, hätten Sie festgestellt, dass Ihre Regeln auf etwa Folgendes eingestellt waren:

match /{document=**} {
  allow read, write: if request.time 



<p>Hier hat Google eine Standardregel erstellt, die einen Zeitstempel verwendet, um ab dem Tag, an dem Sie sie erstellt haben, 30 Tage lang Lese- und Schreibzugriff auf Ihre Datenbank zu ermöglichen. Es ist unwahrscheinlich, dass das jetzt das ist, was Sie wollen (und Google wird Sie sowieso dazu auffordern, es zu ändern). Jetzt ist es an der Zeit, mehr über Firestore-Regeln zu erfahren und wie Sie sie verwenden können, um Ihre Datenbank sicher zu machen.</p>

<h3>
  
  
  Datenbankregeln
</h3>

<p>Mit Firestore-„Regeln“ können Sie den Lese- und Schreibzugriff auf Datenbanksammlungen einschränken, indem Sie auf ein Firebase-Anforderungsobjekt verweisen, das bei jedem Datenbankaufruf an einen Firestore-„Regelhandler“ übergeben wird. Dieses Objekt enthält unter anderem Angaben zum anfragenden Benutzer, zur Art des ausgeführten Vorgangs und zur aktuellen Uhrzeit. Wenn Sie die vollständige Liste der Eigenschaften sehen möchten, stellt Ihnen chatGPT diese gerne zur Verfügung. </p>

<p>Um einen vollständigen Überblick über die Syntax der Firestore-Regeln zu erhalten, verweise ich Sie wahrscheinlich am besten auf die eigenen Dokumente von Google unter „Erste Schritte mit Firestore-Regeln“. Im Moment werde ich mich auf die unmittelbaren Anforderungen an die Standarddatenbank konzentrieren, die in dieser Beitragsreihe erstellt wurde.</p>

<p>Um eine Datenbankregel in Aktion zu sehen, versuchen Sie, die Registerkarte „Regeln“ auf der Firestore-Seite in Ihrer Firebase-Konsole zu verwenden, um Ihre Regeln wie folgt zu ändern:<br>
</p>

<pre class="brush:php;toolbar:false">    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>Diese Regel erlaubt nur Schreibzugriff auf die Dokumente in Ihrer Datenbank, wenn die Zeit vor dem 1. Januar 2000 liegt. Wenn Sie also nicht gerade in einer Zeitmaschine arbeiten, können Sie jetzt keine neue erstellen Dokument.</p>

<p>Klicken Sie auf die Schaltfläche „Veröffentlichen“, um die neue Regel live zu schalten (Sie können die Meldung ignorieren, dass die Veröffentlichung einige Zeit dauern kann, bis sie wirksam wird – in der Praxis scheint die Verzögerung minimal zu sein) und sehen Sie, wie Ihre Webanwendung reagiert </p>

<p>Starten Sie Ihren Entwicklungsserver und starten Sie die Webanwendung unter http://localhost:5173. Wenn Sie versuchen, ein neues Produkt hinzuzufügen, sollten Sie nicht allzu überrascht sein, wenn Sie die Seite „500: Interner Fehler“ erhalten. Wenn Sie zu Ihrer Terminalsitzung gehen, um die Ursache zu untersuchen, wird die folgende Meldung angezeigt:<br>
</p><pre class="brush:php;toolbar:false">match /{document=**} {
  allow read, write: if request.time 



<p>Da Sie nun ein Gefühl dafür haben, wie Firestore-Regeln funktionieren, können Sie darüber nachdenken, wie Sie diese auf den Produktanzeige- und Produktwartungsseiten verwenden könnten, die Sie in Beitrag 3.1 erstellt haben.</p>

<p>Wie Sie sich erinnern werden, boten diese zwei Routen wie folgt an:</p>

  • eine „products-display“-Route unter localhost:5173/products-display, die es Benutzern ermöglicht, alle Dokumente aus der Produktsammlung zu lesen und
  • eine „products-maintenance“-Route unter localhost:5173/products-maintenance, die es Benutzern ermöglicht, neue Dokumente in die Sammlung zu schreiben.

Es wird davon ausgegangen, dass Sie jedem gerne gestatten, Produktdokumente über die Route „Produktanzeige“ zu lesen, Sie möchten jedoch, dass dies nur autorisierten Personen gestattet ist Sie können neue Produkte über die Route „Produkte-Wartung“ hinzufügen.

Einzelpersonen werden autorisiert, indem ihnen eine „Benutzer-ID/Passwort“-Kombination zugewiesen wird, mit der sie sich bei der Webanwendung „anmelden“ können. Durch dieses Verfahren wird ein dauerhafter „Authentifizierungs“-Status auf dem Clientgerät des Benutzers erstellt, der Teil des Firebase-Anforderungsobjekts wird, das an die Firestore-Regelverarbeitung übergeben wird, wenn der Benutzer versucht, auf eine Datenbank zuzugreifen.

Wenn Sie dann die Firestore-Regeln wie folgt festlegen:

    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>Nur ​​„eingeloggte“ Benutzer können auf der Seite „Produkte“ schreiben. </p>

<p>Jetzt müssen Sie nur noch wissen, wie Sie eine „Anmeldeseite“ schreiben, um einen Authentifizierungsstatus zu erstellen. Bitte lesen Sie weiter!</p>

<h3>
  
  
  2. Firebase-Anmeldung
</h3>

<p>In einem Anmeldebildschirm werden potenzielle Systembenutzer aufgefordert, eine persönliche Kennung (normalerweise eine E-Mail-Adresse) und ein zugehöriges Passwort anzugeben. </p>

<p>Das System vergleicht dann die Kennung und das Passwort des Benutzers mit einer sicheren Liste bekannter Anmeldeinformationen. In Firebase finden Sie diese Liste in der Firebase-Konsole Ihres Projekts auf der Registerkarte „Build –> Authentifizierung –> Benutzer“. Schauen Sie sich das an. Nutzen Sie die Gelegenheit, eine Test-E-Mail-Adresse und ein Passwort zu registrieren (eine programmatische Registrierung ist ebenfalls möglich, wird hier aber nicht behandelt). Beachten Sie das „Benutzer-UID-Feld“, das Firebase der Registrierung zuordnet. Dabei handelt es sich um eine eindeutige, verschlüsselte Version der E-Mail-Adresse. Wie Sie gleich sehen werden, ist dies ein wichtiges Element des Firebase-Sicherheitsmechanismus. Beachten Sie auch, dass der Bildschirm Funktionen zum Löschen von Konten und zum Ändern von Passwörtern bietet.</p>

<p>Während Sie hier sind, sehen Sie sich die Registerkarte „Anmeldemethode“ auf dem Bildschirm „Authentifizierung“ an. Es werden E-Mail-/Passwort-Kombinationen oder Google-Konten angeboten. Ich empfehle, dass Sie zu diesem Zeitpunkt nur die E-Mail-/Passwort-Option aktivieren. </p>

<p>Erstellen Sie nun einen Anmeldebildschirm. Der unten gezeigte Beispielcode ist überraschend kurz (und das meiste davon ist Styling!):<br>
</p>

<pre class="brush:php;toolbar:false">[FirebaseError: Missing or insufficient permissions.] {
  code: 'permission-denied',
  customData: undefined,
  toString: [Function (anonymous)]
}

Erstellen Sie neue Routenordner und page.svelte-Dateien für die Anmelde- und Abmeldeskripte. Aber versuchen Sie es noch nicht, sie auszuführen, denn ich muss Ihnen noch ein paar Kleinigkeiten erzählen!

Beachten Sie, dass diese Dateien jetzt ihre Authentifizierungsvariable aus einer zentralen src/lib/utilities/firebase-client.js-Datei importieren. Darin präsentiert die Webanwendung ihre Firebase-Konfigurationsschlüssel, um Firebase zu versichern, dass es berechtigt ist, ein Authentifizierungsobjekt zu erstellen. Hier ist die aktualisierte Version von src/lib/utilities/firebase-client.js, die dies tut.

match /{document=**} {
  allow read, write: if request.time 



<p>Da die hier exportierten App-, Authentifizierungs- und Datenbankvariablen in einer Webanwendung häufig benötigt werden, wird viel Code eingespart, indem sie an einem zentralen Ort generiert werden.  </p>

<p>Aber ein paar „Bling“-Teile hier bedürfen einer Erklärung.</p>

<p>Zunächst werden Sie feststellen, dass ich FirebaseConfig-Eigenschaften wie apiKey nicht mehr <strong>direkt</strong> im Code codiere, sondern auf Vite-Parameter verweise, die ich in der .env-Datei des Projekts definiert habe (eine Datei oder Ordner mit einem „.“ bedeutet, dass es sich um „System“-Daten handelt). Hier ist es:<br>
</p>

<pre class="brush:php;toolbar:false">    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>Der Sinn der .env-Datei besteht darin, Ihre firebaseConfig-Schlüssel in einer Datei abzulegen, die keinen Anwendungscode enthält. Dies erleichtert Ihnen die Verwaltung ihrer Sicherheit erheblich. Aber lassen wir das zunächst beiseite, damit Sie sich auf wichtigere Dinge konzentrieren können. Ich habe am Ende dieses Beitrags eine Notiz hinzugefügt, die hoffentlich alles erklärt.</p>

<p>Eine zweite Funktion, die Sie vielleicht verwirren könnte, ist die const app = !getApps().length ? initializeApp(firebaseConfig) : getApp(); Linie. Dies ist ein Beispiel für eine „ternäre“ Javascript-Anweisung (holen Sie sich chatGPT, um zu erklären, wie es funktioniert, falls Sie das noch nicht kennen). Seine Wirkung ist:</p>

  • Initialisieren Sie eine Firebase-App nur, wenn derzeit keine App in der Firebase-Umgebung vorhanden ist. Die Webanwendung referenziert während einer Benutzersitzung häufig auf firebase-client.js und initializeApp() schlägt fehl, wenn bereits eine App vorhanden ist
  • Andernfalls rufen Sie die vorhandene App ab.

Zurück im Mainstream hat das alles zur Folge, dass Firebase bei erfolgreicher Anmeldung ein „Authentifizierungs“-Objekt für den authentifizierten Benutzer erstellt und dieses sicher in der Browserumgebung ablegt. Firebase kann somit automatisch jedem Anforderungsobjekt, das an eine FireStore-Datenbankdienstanfrage übergeben wird, ein daraus generiertes Authentifizierungstoken hinzufügen. Zu den Informationen im Token gehören Eigenschaften wie die „Benutzer-uID“-ID, die Sie zuvor auf der Registerkarte „Firebase-Authentifizierung“ gesehen haben. Folglich kann Firestore entscheiden, wie eine Regel wie „allow write: if request.auth != null“ angewendet wird.

Das alles bedeutet, dass die clientseitige Firestore-Aktivität wie am Schnürchen funktioniert – sobald Sie angemeldet sind, kümmern sich die Firestore-Regeln um alle Ihre Bedenken hinsichtlich der Datenbanksicherheit.

Aber es gibt einen Haken – einen riesigen Haken sogar. Das „Auth“-Objekt, das Firebase in die Browserumgebung eingefügt hat, ist für serverseitige Seiten wie inventory-maintenance/page.server.js nicht verfügbar.

Sie können dies leicht demonstrieren.

  1. Veröffentlichen Sie neue Firestore-Regeln, die es jedem ermöglichen, alles in der Produktsammlung zu lesen, aber sicherstellen, dass nur authentifizierte Personen Dokumente schreiben können

    match /{document=**} {
      allow read, write: if request.time 
    
    
  2. Melden Sie sich über die Route /login an und erhalten Sie die Meldung „Sie sind mit Google angemeldet“.

  3. Starten Sie die Seite /products-display. Denn die Firestore-Regeln erlauben jedem, alles zu lesen. Auf der Seite wird somit wie bisher die aktuelle Liste der registrierten Produkte angezeigt.

  4. Versuchen Sie, über die Produktwartungsseite ein neues Produkt hinzuzufügen. Ach! Fehler!

    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>Was hier passiert ist, ist, dass die „verdrehte“ Authentifizierungsvariable des Browsers und der Rest seiner übergeordneten Firebase-Sitzungsinformationen für Firestore auf dem Server nicht verfügbar sind. Folglich ist request.auth dort undefiniert und daher schlägt die Firestore-Regel fehl. </p>

<p>Der Standpunkt ist, dass Google es abgelehnt hat, Firebase eine serverseitige Version der hervorragenden Sitzungsverwaltungsfunktion zur Verfügung zu stellen, die das Leben auf der Clientseite so angenehm macht. Derzeit verwendet Ihr Code die Firestore-API <strong>Client</strong>. Auf dem Server, auf dem eine Firestore-Datenbank „Regeln“ für eine Sammlung festgelegt hat, die auf Firebase-Authentifizierungssitzungsvariablen verweist, müssen Sie die Firestore-API <strong>Admin</strong> anstelle der Client-API verwenden. Aufrufe in der Admin-API überprüfen die Firestore-Regeln nicht, schlagen also nicht fehl, wenn die Authentifizierung nicht definiert ist. Die Verwendung der Admin-API hat jedoch mehrere Konsequenzen:</p>

  • Die Admin-API verwendet verschiedene „Anrufsignaturen“. Die Abfolge der Admin-API-Funktionen, die Sie zum serverseitigen Lesen/Schreiben von Datenbankvorgängen verwenden, ähnelt im Großen und Ganzen der Client-Version, verwendet jedoch eine andere Syntax.
  • Für die Admin-API müssen Sie alle Benutzerdaten abrufen, die Sie möglicherweise benötigen, indem Sie Code verwenden, den Sie selbst schreiben. Die clientseitige Firebase-Sitzung, die praktischerweise das unschätzbare auth.currentUser-Objekt zur Bereitstellung von uID, Benutzername usw. bereitgestellt hat, ist serverseitig nicht mehr verfügbar. Sie müssen selbst für einen Ersatz sorgen.

Stöhnen. Gibt es eine Alternative? Die nächsten beiden Beiträge zeigen:

  1. Wie Sie das Problem umgehen können, indem Sie eine „regelfreundliche“ Version Ihrer Webanwendung entwickeln. Die Folge davon ist eine schlechtere Leistung (da serverseitiger Code schneller läuft), eine geringere Sicherheit (da die clientseitige Formularvalidierung unsicher ist) und geringere SEO-Aussichten (da Webspider weniger Begeisterung für die Indizierung von clientseitigem Code haben)
  2. Alternativ, wie Sie weitermachen und eine vollständige „Client-Server“-Version Ihrer Webanwendung entwickeln können. Dadurch erhalten Sie Top-Leistung, Sicherheit und SEO, müssen aber eine weitere Technologiewelle verhandeln, um die Funktionslücken zu schließen, die durch den Verlust der Firebase-Benutzersitzungsvereinbarung entstanden sind

3. Fazit

Das war eine harte Fahrt mit einem unglücklichen Ende. Ich hoffe jedoch, dass Sie die Energie haben, weiterzulesen.

Aus Ihrer Sicht als Entwickler wird regelfreundlicher Code eine wahre Freude sein, da Sie ihn vollständig mit dem Inspector-Tool des Browsers debuggen können. Obwohl es, wie bereits erwähnt, Einschränkungen aufweist, könnte es für viele einfache Anwendungen vollkommen zufriedenstellend sein.

Alternativ stellt die Client-Server-Version zwar einige neue Herausforderungen dar, vermittelt Ihnen aber wertvolle Erfahrungen in gängigen Entwicklungspraktiken und liefert eine wirklich bemerkenswerte Leistung.

Nachtrag – worum geht es in diesem „.env“-Geschäft?

So bizarr es auch klingen mag, alles beginnt mit der Versionskontrollsoftware „Github“ von Microsoft. Dies ist eine kostenlose Webanwendung, mit der Sie Quellkopien in ein persönliches webbasiertes Repository kopieren können. Es ist zu einem Industriestandard geworden und Sie können mehr darüber unter „Eine sanfte Einführung in Git und Github“ erfahren.

Der Hauptzweck besteht darin, die Aktivitäten von Entwicklerteams zu integrieren, die parallel am selben Projekt arbeiten. Aber Sie könnten durchaus daran interessiert sein, es zu verwenden, denn während der Entwicklung und fortlaufenden Verbesserung Ihrer persönlichen Projekte wird es Zeiten geben, in denen Sie einen „Checkpoint“-Snapshot Ihres Codes an einem sicheren Ort platzieren möchten. .

Das Problem besteht darin, dass im Quellcode eingebettete sensible Schlüssel allzu leicht versehentlich in einem Git-Repository gespeichert werden. Obwohl Repositorys als „privat“ markiert werden können, ist die Sicherheit nicht garantiert.

Ein Teil der Antwort besteht darin, die Dinge so zu arrangieren, dass Projektschlüssel getrennt von Codedateien gespeichert werden. Auf diese Weise müssen sie nicht nach Git kopiert werden. Das Platzieren Ihrer Firebase-Schlüssel in Ihrer libutilitiesfirebase-client.js-Datei hat hier geholfen, da dadurch Schlüssel nicht mehr in mehreren page.server.js-Dateien codiert wurden. Aber es gab immer noch Code in der zentralen Datei firebase-client.js, den Sie in Ihrem Repo speichern möchten. Durch die Verwendung der env-Datei können Sie Code endlich von Schlüsseln trennen. Obwohl Ihre .env-Schlüssel in Ihrem Projekt verbleiben, muss diese Datei nicht mehr in das Code-Repository kopiert werden. Es kann daher zur Datei .gitignore hinzugefügt werden, die Git mitteilt, welche Dateien ausgeschlossen werden sollen.

Sie werden feststellen, dass Svelte bei der Initialisierung Ihres Projekts eine .gitignore-Datei erstellt hat und dass diese bereits Details zu Vite-Systemordnern enthält, die keinen Platz in einem Quellcode-Prüfpunkt haben. Um sicherzustellen, dass eine „.env“-Datei (und jeglicher Bearbeitungsverlauf für die Datei) von allen Git-Commits ausgeschlossen ist, würden Sie die folgenden Einträge hinzufügen:

match /{document=**} {
  allow read, write: if request.time 



<p><em>Beachten Sie, dass die Zeile /.env in Ihrem VSCode Workspace-Verzeichnis „ausgegraut“ wird, sobald Sie dies getan haben. Dies bietet visuelle Sicherheit, dass diese Datei nicht durch einen Git-Commit im Web offengelegt wird.</em></p>


          

            
        

Das obige ist der detaillierte Inhalt vonNgSysV.A Serious Svelte InfoSys: Firebase D/b-Regeln und Login. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
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
Ersetzen Sie Stringzeichen in JavaScriptErsetzen Sie Stringzeichen in JavaScriptMar 11, 2025 am 12:07 AM

Detaillierte Erläuterung der Methode für JavaScript -Zeichenfolge und FAQ In diesem Artikel werden zwei Möglichkeiten untersucht, wie String -Zeichen in JavaScript ersetzt werden: Interner JavaScript -Code und interne HTML für Webseiten. Ersetzen Sie die Zeichenfolge im JavaScript -Code Die direkteste Möglichkeit ist die Verwendung der Ersatz () -Methode: str = str.replace ("find", "ersetzen"); Diese Methode ersetzt nur die erste Übereinstimmung. Um alle Übereinstimmungen zu ersetzen, verwenden Sie einen regulären Ausdruck und fügen Sie das globale Flag G hinzu:: STR = Str.Replace (/fi

Benutzerdefinierte Google -Search -API -Setup -TutorialBenutzerdefinierte Google -Search -API -Setup -TutorialMar 04, 2025 am 01:06 AM

Dieses Tutorial zeigt Ihnen, wie Sie eine benutzerdefinierte Google -Such -API in Ihr Blog oder Ihre Website integrieren und ein raffinierteres Sucherlebnis bieten als Standard -WordPress -Themen -Suchfunktionen. Es ist überraschend einfach! Sie können die Suche auf y beschränken

Erstellen Sie Ihre eigenen AJAX -WebanwendungenErstellen Sie Ihre eigenen AJAX -WebanwendungenMar 09, 2025 am 12:11 AM

Hier sind Sie also bereit, alles über dieses Ding namens Ajax zu lernen. Aber was genau ist das? Der Begriff AJAX bezieht sich auf eine lose Gruppierung von Technologien, mit denen dynamische, interaktive Webinhalte erstellt werden. Der Begriff Ajax, ursprünglich von Jesse J geprägt

Beispielfarben JSON -DateiBeispielfarben JSON -DateiMar 03, 2025 am 12:35 AM

Diese Artikelserie wurde Mitte 2017 mit aktuellen Informationen und neuen Beispielen umgeschrieben. In diesem JSON -Beispiel werden wir uns ansehen, wie wir einfache Werte in einer Datei mit JSON -Format speichern können. Mit der Notation des Schlüsselwertpaares können wir jede Art speichern

8 atemberaubende JQuery -Seiten -Layout -Plugins8 atemberaubende JQuery -Seiten -Layout -PluginsMar 06, 2025 am 12:48 AM

Nutzen Sie JQuery für mühelose Webseiten -Layouts: 8 Essential Plugins JQuery vereinfacht das Webseitenlayout erheblich. In diesem Artikel werden acht leistungsstarke JQuery -Plugins hervorgehoben, die den Prozess optimieren, insbesondere nützlich für die manuelle Website -Erstellung

Was ist ' this ' in JavaScript?Was ist ' this ' in JavaScript?Mar 04, 2025 am 01:15 AM

Kernpunkte Dies in JavaScript bezieht sich normalerweise auf ein Objekt, das die Methode "besitzt", aber es hängt davon ab, wie die Funktion aufgerufen wird. Wenn es kein aktuelles Objekt gibt, bezieht sich dies auf das globale Objekt. In einem Webbrowser wird es durch Fenster dargestellt. Wenn Sie eine Funktion aufrufen, wird das globale Objekt beibehalten. Sie können den Kontext mithilfe von Methoden wie CALL (), Apply () und Bind () ändern. Diese Methoden rufen die Funktion mit dem angegebenen Wert und den Parametern auf. JavaScript ist eine hervorragende Programmiersprache. Vor ein paar Jahren war dieser Satz

Verbessern Sie Ihr JQuery -Wissen mit dem Quell BetrachterVerbessern Sie Ihr JQuery -Wissen mit dem Quell BetrachterMar 05, 2025 am 12:54 AM

JQuery ist ein großartiges JavaScript -Framework. Wie in jeder Bibliothek ist es jedoch manchmal notwendig, unter die Motorhaube zu gehen, um herauszufinden, was los ist. Vielleicht liegt es daran, dass Sie einen Fehler verfolgen oder nur neugierig darauf sind, wie JQuery eine bestimmte Benutzeroberfläche erreicht

10 Mobile Cheat Sheets für die mobile Entwicklung10 Mobile Cheat Sheets für die mobile EntwicklungMar 05, 2025 am 12:43 AM

Dieser Beitrag erstellt hilfreiche Cheat -Blätter, Referenzführer, schnelle Rezepte und Code -Snippets für die Entwicklung von Android-, Blackberry und iPhone -App. Kein Entwickler sollte ohne sie sein! Touch Gesten -Referenzhandbuch (PDF) Eine wertvolle Ressource für Desig

See all articles

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

Heiße Werkzeuge

PHPStorm Mac-Version

PHPStorm Mac-Version

Das neueste (2018.2.1) professionelle, integrierte PHP-Entwicklungstool

Herunterladen der Mac-Version des Atom-Editors

Herunterladen der Mac-Version des Atom-Editors

Der beliebteste Open-Source-Editor

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Leistungsstarke integrierte PHP-Entwicklungsumgebung

SAP NetWeaver Server-Adapter für Eclipse

SAP NetWeaver Server-Adapter für Eclipse

Integrieren Sie Eclipse mit dem SAP NetWeaver-Anwendungsserver.

EditPlus chinesische Crack-Version

EditPlus chinesische Crack-Version

Geringe Größe, Syntaxhervorhebung, unterstützt keine Code-Eingabeaufforderungsfunktion