Die Möglichkeit, Benutzer zu identifizieren, ist entscheidend für die Aufrechterhaltung der Sicherheit jeder Anwendung. Ebenso wichtig ist der Code, der zur Verwaltung von Benutzeridentitäten geschrieben wird, insbesondere wenn es darum geht, Lücken für unbefugten Zugriff auf Daten zu vermeiden, die von einer Anwendung gehalten werden. Das Schreiben von Authentifizierungscode ohne ein Framework oder verfügbare Bibliotheken kann sehr zeitaufwendig sein, um es richtig zu machen – ganz zu schweigen von der laufenden Wartung dieses benutzerdefinierten Codes.
Hier kommt Firebase zur Rettung. Seine einsatzbereiten und intuitiven Methoden machen die Einrichtung eines effektiven Benutzeridentitätsmanagements auf einer Website im Handumdrehen möglich. Dieses Tutorial führt uns durch die Implementierung von Benutzerregistrierung, -verifizierung und -authentifizierung.
Firebase v9 SDK führt eine neue modulare API-Oberfläche ein, was zu Änderungen an mehreren seiner Dienste führt, darunter Firebase Authentication. Dieses Tutorial ist auf dem neuesten Stand der Änderungen in v9.
Um dieses Tutorial zu verfolgen, sollten Sie mit React, React Hooks und Firebase Version 8 vertraut sein. Sie sollten auch ein Google-Konto und Node auf Ihrem Computer installiert haben.
Inhaltsverzeichnis
- Einrichtung von Firebase
- Klonen und Einrichten des Starter-Repos
- Integration von Firebase in unsere React-App
- Erstellung der Benutzerregistrierungsfunktionalität
- Verwaltung des Benutzerstatus mit der React Context API
- Senden einer Bestätigungs-E-Mail an einen registrierten Benutzer
- Arbeiten auf der Benutzerprofilseite
- Erstellung einer privaten Route für die Profilkomponente
- Erstellung der Login-Funktionalität
- Fazit
- Referenzen
Einrichtung von Firebase
Bevor wir Firebase für unsere Registrierungs- und Authentifizierungsanforderungen nutzen, müssen wir zuerst unser Firebase-Projekt und auch die verwendete Authentifizierungsmethode einrichten.
Um ein Projekt hinzuzufügen, stellen Sie sicher, dass Sie in Ihrem Google-Konto angemeldet sind, navigieren Sie dann zur Firebase-Konsole und klicken Sie auf Projekt hinzufügen. Geben Sie dem Projekt einen Namen (ich verwende "Firebase-user-reg-auth") und wir sind bereit, fortzufahren.

Möglicherweise werden Sie irgendwann aufgefordert, Google Analytics zu aktivieren. Für dieses Tutorial ist dies nicht erforderlich, daher können Sie diesen Schritt überspringen.

Firebase bietet verschiedene Authentifizierungsmethoden für Mobilgeräte und Web, aber bevor wir eine davon verwenden, müssen wir sie zuerst auf der Firebase-Authentifizierungsseite aktivieren. Klicken Sie im Seitenmenü auf das Symbol Authentifizierung und dann auf der nächsten Seite auf Erste Schritte.

Wir werden die E-Mail/Passwort-Authentifizierung verwenden. Klicken Sie darauf, und Sie werden aufgefordert, diese zu aktivieren, was genau das ist, was wir tun wollen.

Klonen und Einrichten des Starter-Repos
Ich habe bereits eine einfache Vorlage erstellt, die wir für dieses Tutorial verwenden können, damit wir uns speziell auf das Erlernen der Implementierung der Funktionalitäten konzentrieren können. Was wir jetzt tun müssen, ist, das GitHub-Repo zu klonen.
Starten Sie Ihr Terminal. Hier ist, was wir von der Kommandozeile aus ausführen können
git clone -b starter https://github.com/Tammibriggs/Firebase_user_auth.git
cd Firebase_user_auth
npm install
Ich habe auch Firebase Version 9 in das Abhängigkeitsobjekt der Datei package.json aufgenommen. Durch Ausführen des Befehls npm install werden Firebase v9 – zusammen mit allen anderen Abhängigkeiten – installiert.
Nachdem dies geschehen ist, starten wir die App mit npm start!
Integration von Firebase in unsere React-App
Um Firebase zu integrieren, müssen wir zuerst das Web-Konfigurationsobjekt abrufen und es dann verwenden, um Firebase in unserer React-App zu initialisieren. Gehen Sie zur Firebase-Projektseite und Sie sehen eine Reihe von Optionen als Symbole wie diese

Klicken Sie auf das Web-Symbol (</>), um unser Firebase-Projekt für das Web zu konfigurieren, und Sie sehen eine Seite wie diese

Geben Sie firebase-user-auth als Namen der Web-App ein. Klicken Sie danach auf die Schaltfläche App registrieren, die uns zum nächsten Schritt führt, wo unser firebaseConfig-Objekt bereitgestellt wird.

Kopieren Sie die Konfiguration in die Zwischenablage, da wir sie später zur Initialisierung von Firebase benötigen. Klicken Sie dann auf die Schaltfläche Weiter zur Konsole, um den Vorgang abzuschließen.
Nun initialisieren wir Firebase und Firebase Authentication, damit wir sie in unserer App verwenden können. Erstellen Sie im Verzeichnis src unserer React-App eine Datei firebase.js und fügen Sie die folgenden Importe hinzu
// src/firebase.js
import { initializeApp } from 'firebase/app'
import {getAuth} from 'firebase/auth'
Fügen Sie nun die zuvor kopierte Konfiguration nach den Importen ein und fügen Sie die folgenden Codezeilen hinzu, um Firebase und Firebase Authentication zu initialisieren.
// src/firebase.js
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)
export {auth}
Unsere Datei firebase.js sollte nun ungefähr so aussehen
// src.firebase.js
import { initializeApp } from "firebase/app"
import { getAuth } from "firebase/auth"
const firebaseConfig = {
apiKey: "API_KEY",
authDomain: "AUTH_DOMAIN",
projectId: "PROJECT_ID",
storageBucket: "STORAGE_BUCKET",
messagingSenderId: "MESSAGING_SENDER_ID",
appId: "APP_ID"
}
// Initialize Firebase and Firebase Authentication
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)
export {auth}
Als Nächstes behandeln wir, wie die einsatzbereiten Funktionen von Firebase verwendet werden, um Registrierungs-, E-Mail-Verifizierungs- und Login-Funktionen zur geklonten Vorlage hinzuzufügen.
Erstellung der Benutzerregistrierungsfunktionalität
In Firebase Version 9 können wir mit der Funktion createUserWithEmailAndPassword Funktionalität für die Benutzerregistrierung erstellen. Diese Funktion nimmt drei Argumente entgegen
- Auth-Instanz/Dienst
- Passwort
Dienste werden in Version 9 immer als erstes Argument übergeben. In unserem Fall ist es der Auth-Dienst.
Um diese Funktionalität zu erstellen, werden wir mit der Datei Register.js im Verzeichnis src unserer geklonten Vorlage arbeiten. Was ich in dieser Datei getan habe, ist, drei Formularfelder zu erstellen – E-Mail, Passwort und Bestätigungspasswort – und die Eingaben werden durch den Status gesteuert. Nun, lassen Sie uns zur Sache kommen.
Beginnen wir mit dem Hinzufügen einer Funktion, die die Eingaben für Passwort und Bestätigungspasswort validiert, prüft, ob sie nicht leer sind und übereinstimmen: Fügen Sie die folgenden Codezeilen nach den States in der Komponente Register hinzu
// src/Register.js
// ...
const validatePassword = () => {
let isValid = true
if (password !== '' && confirmPassword !== ''){
if (password !== confirmPassword) {
isValid = false
setError('Passwords does not match')
}
}
return isValid
}
// ...
In der obigen Funktion geben wir eine Variable isValid zurück, die je nach Gültigkeit der Passwörter entweder true oder false zurückgeben kann. Später werden wir den Wert dieser Variablen verwenden, um eine Bedingung zu schaffen, unter der die Firebase-Funktion zur Registrierung von Benutzern nur dann aufgerufen wird, wenn isValid true ist.
Um die Registrierungsfunktionalität zu erstellen, beginnen wir damit, die notwendigen Importe in die Datei Register.js zu machen
// src/Register.js
import {auth} from './firebase'
import {createUserWithEmailAndPassword} from 'firebase/auth'
Fügen Sie nun die folgenden Codezeilen nach der Funktion validatePassword hinzu
// src/Register.js
// ...
const register = e => {
e.preventDefault()
setError('')
if(validatePassword()) {
// Create a new user with email and password using firebase
createUserWithEmailAndPassword(auth, email, password)
.then((res) => {
console.log(res.user)
})
.catch(err => setError(err.message))
}
setEmail('')
setPassword('')
setConfirmPassword('')
}
// ...
In der obigen Funktion setzen wir eine Bedingung, um die Funktion createUserWithEmailAndPassword nur dann aufzurufen, wenn der Wert, der von validatePassword zurückgegeben wird, true ist.
Damit dies zu funktionieren beginnt, rufen wir die Funktion register auf, wenn das Formular abgesendet wird. Dies können wir tun, indem wir ein onSubmit-Ereignis zum Formular hinzufügen. Modifizieren Sie das öffnende Tag des registration_form wie folgt
// src/Register.js
<form onSubmit={register} name='registration_form'>
Damit können wir nun einen neuen Benutzer auf unserer Website registrieren. Um dies zu testen, gehen Sie zu https://:3000/register im Browser, füllen Sie das Formular aus und klicken Sie dann auf die Schaltfläche Registrieren.

Nachdem Sie auf die Schaltfläche Registrieren geklickt haben, sehen wir im Konsolenfenster des Browsers Details zum neu registrierten Benutzer.
Verwaltung des Benutzerstatus mit der React Context API
Context API ist eine Möglichkeit, Daten mit Komponenten auf jeder Ebene des React-Komponentenbaums zu teilen ohne sie als Props weitergeben zu müssen. Da ein Benutzer möglicherweise von einer anderen Komponente im Baum benötigt wird, ist die Verwendung der Context API großartig für die Verwaltung des Benutzerstatus.
Bevor wir mit der Verwendung der Context API beginnen, müssen wir einige Dinge einrichten
- Erstellen Sie ein Kontextobjekt mit der Methode
createContext() - Übergeben Sie die Komponenten, mit denen wir den Benutzerstatus teilen möchten, als Kinder von Context.Provider
- Übergeben Sie den Wert, den die Kind-/Konsumentenkomponente abrufen soll, als Props an
Context.Provider
Legen wir los. Erstellen Sie im Verzeichnis src eine Datei AuthContext.js und fügen Sie die folgenden Codezeilen hinzu
// src/AuthContext.js
import React, {useContext} from 'react'
const AuthContext = React.createContext()
export function AuthProvider({children, value}) {
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
}
export function useAuthValue(){
return useContext(AuthContext)
}
Im obigen Code haben wir einen Kontext namens AuthContext erstellt. Außerdem haben wir zwei weitere Funktionen erstellt, die uns die einfache Verwendung der Context API ermöglichen: AuthProvider und useAuthValue.
Die Funktion AuthProvider ermöglicht es uns, den Wert des Benutzerstatus mit allen Kindern von AuthContext.Provider zu teilen, während useAuthValue uns den einfachen Zugriff auf den an AuthContext.Provider übergebenen Wert ermöglicht.
Um nun die Props für Kinder und Werte an AuthProvider zu übergeben, modifizieren Sie die Datei App.js wie folgt
// src/App.js
// ...
import {useState} from 'react'
import {AuthProvider} from './AuthContext'
function App() {
const [currentUser, setCurrentUser] = useState(null)
return (
<Router>
<AuthProvider value={{currentUser}}>
<Switch>
...
</Switch>
</AuthProvider>
</Router>
);
}
export default App;
Hier umschließen wir die von App gerenderten Komponenten mit AuthProvider. Auf diese Weise ist der currentUser-Wert, der an AuthProvider übergeben wird, für alle Komponenten unserer App außer der App-Komponente verfügbar.
Das war's, was die Einrichtung der Context API betrifft! Um sie zu verwenden, müssen wir die Funktion useAuthValue importieren und sie in einer der Kindkomponenten von AuthProvider aufrufen, wie z. B. Login. Der Code sieht ungefähr so aus
import { useAuthValue } from "./AuthContext"
function childOfAuthProvider(){
const {currentUser} = useAuthValue()
console.log(currentUser)
return ...
}
Derzeit ist currentUser immer null, da wir ihm keinen Wert zuweisen. Um seinen Wert festzulegen, müssen wir zuerst den aktuellen Benutzer von Firebase abrufen, was entweder durch die Verwendung der in unserer Datei firebase.js initialisierten Auth-Instanz (auth.currentUser) oder durch die Funktion onAuthStateChanged geschehen kann, die tatsächlich die empfohlene Methode zum Abrufen des aktuellen Benutzers ist. So stellen wir sicher, dass das Auth-Objekt sich nicht in einem Zwischenzustand befindet – wie z. B. der Initialisierung –, wenn wir den aktuellen Benutzer abrufen.
Fügen Sie in der Datei App.js einen Import für useEffect zusammen mit useState hinzu und fügen Sie außerdem die folgenden Importe hinzu
// src/App.js
import {useState, useEffect} from 'react'
import {auth} from './firebase'
import {onAuthStateChanged} from 'firebase/auth'
Fügen Sie nun die folgende Codezeile nach dem currentUser-Status in der App-Komponente hinzu
// src/App.js
// ...
useEffect(() => {
onAuthStateChanged(auth, (user) => {
setCurrentUser(user)
})
}, [])
// ...
Im obigen Code erhalten wir den aktuellen Benutzer und legen ihn beim Rendern der Komponente im Status fest. Wenn wir nun einen Benutzer registrieren, wird der Status currentUser mit einem Objekt festgelegt, das die Benutzerinformationen enthält.
Senden einer Bestätigungs-E-Mail an einen registrierten Benutzer
Sobald ein Benutzer registriert ist, möchten wir, dass er seine E-Mail-Adresse verifiziert, bevor er Zugriff auf die Homepage unserer Website erhält. Wir können die Funktion sendEmailVerification dafür verwenden. Sie nimmt nur ein Argument entgegen, nämlich das Objekt des aktuell registrierten Benutzers. Wenn sie aufgerufen wird, sendet Firebase eine E-Mail an die E-Mail-Adresse des registrierten Benutzers mit einem Link, über den der Benutzer seine E-Mail verifizieren kann.
Gehen wir zur Datei Register.js und modifizieren Sie den Import von Link und createUserWithEmailAndPassword wie folgt
// src/Register.js
import {useHistory, Link} from 'react-router-dom'
import {createUserWithEmailAndPassword, sendEmailVerification} from 'firebase/auth'
Im obigen Code haben wir auch den Hook useHistory importiert. Dieser hilft uns beim Zugriff auf und der Manipulation der Browserhistorie, was kurz gesagt bedeutet, dass wir ihn verwenden können, um zwischen Seiten in unserer App zu wechseln. Aber bevor wir ihn verwenden können, müssen wir ihn aufrufen, also fügen wir die folgende Codezeile nach dem error-Status hinzu
// src/Register.js
// ...
const history = useHistory()
// ...
Modifizieren Sie nun die Methode .then der Funktion createUserWithEmailAndPassword wie folgt
// src/Register.js
// ...
.then(() => {
sendEmailVerification(auth.currentUser)
.then(() => {
history.push('/verify-email')
}).catch((err) => alert(err.message))
})
// ...
Was hier passiert ist, dass, wenn ein Benutzer eine gültige E-Mail-Adresse registriert, ihm eine Bestätigungs-E-Mail gesendet und dann zur Seite verify-email weitergeleitet wird.

Es gibt mehrere Dinge, die wir auf dieser Seite tun müssen
- Anzeige der E-Mail des Benutzers nach dem Satz „Eine Bestätigungs-E-Mail wurde gesendet an:“
- Die Schaltfläche E-Mail erneut senden funktionsfähig machen
- Erstellung einer Funktionalität zur Deaktivierung der Schaltfläche E-Mail erneut senden für 60 Sekunden nach dem Klicken
- Weiterleitung des Benutzers zu seiner Profilseite, sobald die E-Mail verifiziert wurde
Wir beginnen damit, die E-Mail des registrierten Benutzers anzuzeigen. Dies erfordert die Verwendung des AuthContext, den wir zuvor erstellt haben. Fügen Sie in der Datei VerifyEmail.js den folgenden Import hinzu
// src/VerifyEmail.js
import {useAuthValue} from './AuthContext'
Fügen Sie dann den folgenden Code vor der return-Anweisung in der Komponente VerifyEmail hinzu
// src/VerifyEmail.js
const {currentUser} = useAuthValue()
Nun fügen Sie den folgenden Code nach dem <br/>-Tag in der return-Anweisung ein, um die E-Mail anzuzeigen.
// src/VerifyEmail.js
// ...
<span>{currentUser?.email}</span>
// ...
Im obigen Code verwenden wir optionales Chaining, um die E-Mail des Benutzers abzurufen, damit unser Code keine Fehler auslöst, wenn die E-Mail null ist.
Wenn wir nun die Seite verify-email aktualisieren, sollten wir die E-Mail des registrierten Benutzers sehen.
Kommen wir zum nächsten Punkt: der Funktionalität der Schaltfläche E-Mail erneut senden. Machen wir zuerst die notwendigen Importe. Fügen Sie die folgenden Importe zur Datei VerifyEmail.js hinzu
// src/VerifyEmail.js
import {useState} from 'react'
import {auth} from './firebase'
import {sendEmailVerification} from 'firebase/auth'
Fügen wir nun einen Status hinzu, der für die Deaktivierung und Aktivierung der Schaltfläche E-Mail erneut senden verantwortlich ist, je nachdem, ob die Bestätigungs-E-Mail gesendet wurde oder nicht. Dieser Code kommt nach currentUser in der Komponente VerifyEmail
// src/VerifyEmail.js
const [buttonDisabled, setButtonDisabled] = useState(false)
Für die Funktion, die das erneute Senden der Bestätigungs-E-Mail und das Deaktivieren/Aktivieren der Schaltfläche handhabt, benötigen wir dies nach dem Status buttonDisabled
// src/VerifyEmail.js
// ...
const resendEmailVerification = () => {
setButtonDisabled(true)
sendEmailVerification(auth.currentUser)
.then(() => {
setButtonDisabled(false)
}).catch((err) => {
alert(err.message)
setButtonDisabled(false)
})
}
// ...
Als Nächstes modifizieren wir in der return-Anweisung die Schaltfläche E-Mail erneut senden wie folgt
// ...
<button
onClick={resendEmailVerification}
disabled={buttonDisabled}
>Resend Email</button>
// ...
Wenn wir nun zur Bestätigungs-E-Mail-Seite gehen und die Schaltfläche klicken, wird uns eine weitere E-Mail gesendet. Aber es gibt ein Problem mit der Art und Weise, wie wir diese Funktionalität erstellt haben, denn wenn wir versuchen, die Schaltfläche erneut in weniger als einer Minute zu klicken, erhalten wir einen Fehler von Firebase, dass wir zu viele Anfragen gesendet haben. Das liegt daran, dass Firebase ein Intervall von einer Minute hat, bevor es in der Lage ist, eine weitere E-Mail an dieselbe Adresse zu senden. Das ist das Nächstkommende, das wir angehen müssen.
Wir müssen die Schaltfläche nach dem Senden einer Bestätigungs-E-Mail 60 Sekunden (oder länger) deaktiviert lassen. Wir können das Benutzererlebnis ein wenig verbessern, indem wir auf der Schaltfläche E-Mail erneut senden einen Countdown-Timer anzeigen, damit der Benutzer weiß, dass die Schaltfläche nur vorübergehend deaktiviert ist.
Fügen Sie in der Datei VerifyEmail.js einen Import für useEffect hinzu
import {useState, useEffect} from 'react'
Fügen Sie als Nächstes die folgenden Zeilen nach dem Status buttonDisabled hinzu
// src/VerifyEmail.js
const [time, setTime] = useState(60)
const [timeActive, setTimeActive] = useState(false)
Im obigen Code haben wir einen Status time erstellt, der für den 60-Sekunden-Countdown verwendet wird, und auch einen Status timeActive, der verwendet wird, um zu steuern, wann der Countdown beginnt.
Fügen Sie die folgenden Codezeilen nach den gerade erstellten States hinzu
// src/VerifyEmail.js
// ...
useEffect(() => {
let interval = null
if(timeActive && time !== 0 ){
interval = setInterval(() => {
setTime((time) => time - 1)
}, 1000)
}else if(time === 0){
setTimeActive(false)
setTime(60)
clearInterval(interval)
}
return () => clearInterval(interval);
}, [timeActive, time])
// ...
Im obigen Code haben wir einen useEffect-Hook erstellt, der nur ausgeführt wird, wenn sich der Status timeActive oder time ändert. In diesem Hook verringern wir den vorherigen Wert des Status time jede Sekunde um eins, indem wir die Methode setInterval verwenden, und stoppen dann die Dekrementierung des Status time, wenn sein Wert Null erreicht.
Da der Hook useEffect vom Status timeActive und time abhängt, muss einer dieser States geändert werden, bevor der Countdown beginnen kann. Die Änderung des Status time ist keine Option, da der Countdown erst beginnen muss, wenn eine Bestätigungs-E-Mail gesendet wurde. Stattdessen müssen wir den Status timeActive ändern.
Modifizieren Sie in der Funktion resendEmailVerification die Methode .then von sendEmailVerification wie folgt
// src/VerifyEmail.js
// ...
.then(() => {
setButtonDisabled(false)
setTimeActive(true)
})
// ...
Nun, wenn eine E-Mail gesendet wird, ändert sich der Status timeActive auf true und der Countdown beginnt. Im obigen Code müssen wir ändern, wie wir die Schaltfläche deaktivieren, denn wenn der Countdown aktiv ist, wollen wir die deaktivierte Schaltfläche.
Das werden wir gleich tun, aber im Moment machen wir den Countdown für den Benutzer sichtbar. Modifizieren Sie die Schaltfläche E-Mail erneut senden wie folgt
// src/VerifyEmail.js
<button
onClick={resendEmailVerification}
disabled={buttonDisabled}
>Resend Email {timeActive && time}</button>
Um die Schaltfläche während des aktiven Countdowns deaktiviert zu halten, modifizieren wir das disabled-Attribut der Schaltfläche wie folgt
disabled={timeActive}
Damit wird die Schaltfläche eine Minute lang deaktiviert, wenn eine Bestätigungs-E-Mail gesendet wird. Nun können wir den Status buttonDisabled aus unserem Code entfernen.
Obwohl diese Funktionalität funktioniert, gibt es immer noch ein Problem mit der Implementierung: Wenn ein Benutzer sich registriert und zur Seite verify-email weitergeleitet wird, wenn er noch keine E-Mail erhalten hat, kann er versuchen, auf die Schaltfläche E-Mail erneut senden zu klicken, und wenn er dies in weniger als einer Minute tut, gibt Firebase erneut einen Fehler aus, da wir zu viele Anfragen gestellt haben.
Um dies zu beheben, müssen wir die Schaltfläche E-Mail erneut senden 60 Sekunden lang deaktiviert lassen, *nachdem* eine E-Mail an den neu registrierten Benutzer gesendet wurde. Das bedeutet, wir brauchen eine Möglichkeit, den Status timeActive innerhalb der Komponente Register zu ändern. Wir können dafür auch die Context API verwenden. Sie ermöglicht es uns, den Status timeActive global zu manipulieren und darauf zuzugreifen.
Wir nehmen einige Änderungen an unserem Code vor, damit die Dinge richtig funktionieren. In der Komponente VerifyEmail schneiden Sie den Status timeActive aus und fügen ihn in die Komponente App nach dem Status currentUser ein.
// src/App.js
function App() {
// ...
const [timeActive, setTimeActive] = useState(false)
// ...
Setzen Sie als Nächstes timeActive und setTimeActive in das Objekt des Wert-Props von AuthProvider. Es sollte wie folgt aussehen
// src/App.js
// ...
<AuthProvider value={{currentUser, timeActive, setTimeActive}}>
// ...
Nun können wir timeActive und setTimeActive innerhalb der Kinder von AuthProvider abrufen. Um den Fehler in unserem Code zu beheben, gehen Sie zur Datei VerifyEmail.js und de-strukturieren Sie sowohl timeActive als auch setTimeActive aus useAuthProvider
// src/VerifyEmail.js
const {timeActive, setTimeActive} = useAuthValue()
Fügen Sie nun die folgende Importanweisung zur Datei Register.js hinzu, um den Status timeActive zu ändern, nachdem eine Bestätigungs-E-Mail an den registrierten Benutzer gesendet wurde
// src/Register.js
import {useAuthValue} from './AuthContext'
De-strukturieren Sie als Nächstes setTimeActive aus useAuthValue mit diesem Snippet inmitten der anderen States in der Komponente Register
// src/Register.js
const {setTimeActive} = useAuthValue()
Schließlich setzen Sie in der Funktion register den Status timeActive mit der Methode .then von sendEmailVerification
// src/Register.js
// ...
.then(() => {
setTimeActive(true)
history.push('/verify-email')
})
// ...
Damit kann ein Benutzer eine Bestätigungs-E-Mail senden, ohne Fehler von Firebase zu erhalten.
Das Letzte, was wir bezüglich der Benutzerverifizierung beheben müssen, ist, den Benutzer nach der Verifizierung seiner E-Mail zu seiner Profilseite weiterzuleiten. Dazu verwenden wir eine Funktion reload im Objekt currentUser. Sie ermöglicht es uns, das aus Firebase kommende Benutzerobjekt neu zu laden, sodass wir wissen, wenn sich etwas geändert hat.
Zuerst machen wir die notwendigen Importe. Fügen wir in der Datei VerifyEmail.js Folgendes hinzu
// src/VerifyEmail.js
import {useHistory} from 'react-router-dom'
Wir importieren useHistory, damit wir es verwenden können, um den Benutzer zur Profilseite zu navigieren. Fügen Sie als Nächstes die folgende Codezeile nach den States hinzu
// src/VerifyEmail.js
const history = useHistory()
Und schließlich fügen Sie die folgenden Codezeilen nach der Variablen history hinzu
// src/VerifyEmail.js
// ...
useEffect(() => {
const interval = setInterval(() => {
currentUser?.reload()
.then(() => {
if(currentUser?.emailVerified){
clearInterval(interval)
history.push('/')
}
})
.catch((err) => {
alert(err.message)
})
}, 1000)
}, [history, currentUser])
// ...
Im obigen Code führen wir die Funktion reload jede Sekunde aus, bis die E-Mail des Benutzers verifiziert wurde, und wenn dies der Fall ist, navigieren wir den Benutzer zu seiner Profilseite.
Um dies zu testen, verifizieren wir unsere E-Mail, indem wir den Anweisungen in der von Firebase gesendeten E-Mail folgen. Wenn alles gut ist, werden wir automatisch zu unserer Profilseite weitergeleitet.

Derzeit zeigt die Profilseite keine Benutzerdaten an und der Link Abmelden funktioniert nicht. Das ist unsere nächste Aufgabe.
Arbeiten auf der Benutzerprofilseite
Beginnen wir mit der Anzeige der Werte E-Mail und E-Mail verifiziert. Dazu verwenden wir den Status currentUser in AuthContext. Was wir tun müssen, ist, useAuthValue zu importieren, currentUser daraus zu de-strukturieren und dann den Wert E-Mail und E-Mail verifiziert aus dem Benutzerobjekt anzuzeigen.
Hier ist, wie die Datei Profile.js aussehen sollte
// src/Profile.js
import './profile.css'
import {useAuthValue} from './AuthContext'
function Profile() {
const {currentUser} = useAuthValue()
return (
<div className='center'>
<div className='profile'>
<h1>Profile</h1>
<p><strong>Email: </strong>{currentUser?.email}</p>
<p>
<strong>Email verified: </strong>
{`${currentUser?.emailVerified}`}
</p>
<span>Sign Out</span>
</div>
</div>
)
}
export default Profile
Damit sollten die Werte E-Mail und E-Mail verifiziert nun auf unserer Profilseite angezeigt werden.
Um die Funktionalität Abmelden zu aktivieren, verwenden wir die Funktion signOut. Sie nimmt nur ein Argument entgegen, nämlich die auth-Instanz. Also, in Profile.js, fügen wir diese Importe hinzu.
// src/Profile.js
import { signOut } from 'firebase/auth'
import { auth } from './firebase'
Nun modifizieren wir in der return-Anweisung das <span>, das "Abmelden" enthält, so, dass es die Funktion signOut aufruft, wenn es geklickt wird
// src/Profile.js
// ...
<span onClick={() => signOut(auth)}>Sign Out</span>
// ...
Erstellung einer privaten Route für die Profilkomponente
Derzeit kann ein Benutzer, auch mit einer unverifizierten E-Mail-Adresse, auf die Profilseite zugreifen. Das wollen wir nicht. Unverifizierte Benutzer sollten zur Login-Seite weitergeleitet werden, wenn sie versuchen, auf das Profil zuzugreifen. Hier kommen private Routen ins Spiel.
Erstellen wir im Verzeichnis src eine neue Datei PrivateRoute.js und fügen Sie den folgenden Code hinzu
// src/PrivateRoute.js
import {Route, Redirect} from 'react-router-dom'
import {useAuthValue} from './AuthContext'
export default function PrivateRoute({component:Component, ...rest}) {
const {currentUser} = useAuthValue()
return (
<Route
{...rest}
render={props => {
return currentUser?.emailVerified ? <Component {...props} /> : <Redirect to='/login' />
}}>
</Route>
)
}
Dieses PrivateRoute ist fast ähnlich wie die Verwendung von Route. Der Unterschied ist, dass wir eine render-Prop verwenden, um den Benutzer zur Profilseite umzuleiten, wenn seine E-Mail unverifiziert ist.
Wir möchten, dass die Profilseite privat ist, also importieren wir PrivateRoute
// src/App.js
import PrivateRoute from './PrivateRoute'
Dann können wir Route durch PrivateRoute in der Komponente Profile ersetzen. Die Profile-Route sollte nun wie folgt aussehen
// src/App.js
<PrivateRoute exact path="/" component={Profile} />
Sehr gut! Wir haben die Profilseite nur für Benutzer mit verifizierten E-Mails zugänglich gemacht.
Erstellung der Login-Funktionalität
Da nur Benutzer mit verifizierten E-Mails über die Funktion signInWithEmailAndPassword auf ihre Profilseite zugreifen können, müssen wir auch prüfen, ob ihre E-Mail verifiziert wurde, und wenn sie nicht verifiziert ist, sollte der Benutzer zur Seite verify-email weitergeleitet werden, wo der sechzigsekündige Countdown ebenfalls beginnen sollte.
Dies sind die Importe, die wir zur Datei Login.js hinzufügen müssen
import {signInWithEmailAndPassword, sendEmailVerification} from 'firebase/auth'
import {auth} from './firebase'
import {useHistory} from 'react-router-dom'
import {useAuthValue} from './AuthContext'
Fügen Sie als Nächstes die folgende Codezeile inmitten der States in der Komponente Login hinzu.
// src/Login.js
const {setTimeActive} = useAuthValue()
const history = useHistory()
Fügen Sie dann die folgende Funktion nach der Variablen history hinzu
// src/Login.js
// ...
const login = e => {
e.preventDefault()
signInWithEmailAndPassword(auth, email, password)
.then(() => {
if(!auth.currentUser.emailVerified) {
sendEmailVerification(auth.currentUser)
.then(() => {
setTimeActive(true)
history.push('/verify-email')
})
.catch(err => alert(err.message))
}else{
history.push('/')
}
})
.catch(err => setError(err.message))
}
// ...
Dies loggt einen Benutzer ein und prüft dann, ob er verifiziert ist oder nicht. Wenn er verifiziert ist, navigieren wir ihn zu seiner Profilseite. Wenn er aber nicht verifiziert ist, senden wir eine Bestätigungs-E-Mail und leiten ihn dann zur Seite verify-email weiter.
Alles, was wir tun müssen, um dies zum Laufen zu bringen, ist, die Funktion login aufzurufen, wenn das Formular abgesendet wird. Modifizieren wir also das öffnende Tag des login_form wie folgt
// src/Login.js
<form onSubmit={login} name='login_form'>
Und, hey, wir sind fertig!
Fazit
In diesem Tutorial haben wir gelernt, wie wir die Firebase Authentication Version 9 verwenden, um einen voll funktionsfähigen Benutzerregistrierungs- und Authentifizierungsservice in React zu erstellen. Ist es super einfach? Nein, es gibt ein paar Dinge, die wir jonglieren müssen. Aber ist es verdammt viel einfacher, als unseren eigenen Dienst von Grund auf neu zu entwickeln? Aber sicher! Und das ist es, was ich hoffe, Sie aus dieser Lektüre mitgenommen haben.
Referenzen
- Erste Schritte mit Firebase Authentication auf Websites (Firebase-Dokumentation)
- Benutzer in Firebase verwalten (Firebase-Dokumentation)
Gut, aber ich würde stattdessen die Authentifizierung über Google, Facebook usw. empfehlen. Dies wird von Firebase gut unterstützt.
Ist das mit React Router V6 funktionsfähig? Habe den Code noch nicht ausprobiert, aber ich weiß, dass sich in Version 6 viel geändert hat
Nein, ist es nicht. Ich habe React Router V5 verwendet
Ist es beabsichtigt, dass man sich nach einem manuellen Aktualisieren der Seite erneut anmelden muss, nachdem man sich bereits angemeldet hat? Ich hatte ein ähnliches Problem, als ich diesem Tutorial folgte, und ich glaube, es hat damit zu tun, dass der Benutzer null ist, wenn er zuerst durch den React Context weitergegeben wird, bevor er bevölkert wird, aber zu diesem Zeitpunkt hat die Umleitung bereits stattgefunden.
Hallo M, im Artikel habe ich nicht die Funktionalität hinzugefügt, bei der ein eingeloggter Benutzer zur Profilseite weitergeleitet wird, auch nach einem Browser-Refresh, aber wenn Sie das tun möchten, können Sie den ternären Operator oder eine If-Anweisung verwenden, um die Register- und Login-Seite bedingt basierend auf dem Status des Benutzers zu rendern, etwa so
{
}!currentUser?.emailVerified
?
:
Ich habe den Hauptzweig des Repos mit dieser Funktionalität aktualisiert, damit Sie genau sehen können, wie ich es dort gemacht habe.
Fantastisches Tutorial,
@Taminoturoko Briggs, ich folge dem Code exakt wie Sie ihn geschrieben haben, ich habe auch Ihr Repo geklont, aber das Problem, das ich habe, ist, dass ich nach der Eingabe meiner eigenen Firebase-Projektkonfiguration keine E-Mail zur Bestätigung der E-Mail an die angegebene E-Mail-Adresse erhalte. Bitte sagen Sie mir, woran es liegt.
Überprüfen Sie Ihren Spam-Ordner, dort habe ich sie gefunden.
Was genau ist der Zweck von {children} unten? Der Parameter children wird nirgendsher übernommen, ist er also leer und tut nichts?
export function AuthProvider({children, value}) {
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
}
d.h. würde unten nicht dasselbe bewirken?
export function AuthProvider() {
return (
<AuthContext.Provider value={value}>
</AuthContext.Provider>
)
}
toller Artikel. Ich habe ihn geliebt. Der obige Code funktioniert für React-Router-Dom Version 5, aber das Git-Repository wurde für Version 6 aktualisiert.
Wenn der Entwicklungsserver startet, sehe ich die Profilseite und nicht das Formular, obwohl ich noch kein Konto erstellt oder mich angemeldet habe!
Vielen Dank dafür! Ich habe überall nach getUserAuth-Status gesucht und Ihrer war derjenige, der funktionierte!
Sehr gutes und hilfreiches Tutorial, können Sie mir bitte erklären, wie ich die Weiterleitung nach dem Logout ändern kann?
Vielen Dank und auch danke für Ihr Tutorial :)