Wie fügt man Authentifizierung zu einer React Native App hinzu?
Authentifizierung ist eine Kernkomponente fast jeder App.
Dieser praktische Artikel bietet eine Schritt-für-Schritt-Anleitung für den Einstieg in die Authentifizierung mit React Native.
Darüber hinaus werden die Grundlagen der Authentifizierung, der Vergleich mit der Autorisierung, der Ablauf der Authentifizierung und die Vorteile ihrer Verwendung beschrieben.
Contents
- 1 Was ist Authentifizierung?
- 2 Ablauf der Authentifizierung
- 3 Authentication vs. Authorization
- 4 Vorteile der Authentifizierung
- 5 Wie fügt man Authentifizierung zu einer React Native App hinzu?
- 6 Zusammenfassung
Was ist Authentifizierung?
Authentifizierung ist der Prozess der Verifizierung der Identität einer Person. Im Allgemeinen gibt es drei Arten der Authentifizierung, entweder mit:
- Etwas, das Sie wissen (z. B. Passwort, PIN)
- Etwas, das Sie haben (z. B. Mobiltelefon, Schlüssel)
- Etwas, das Sie sind (z. B. Fingerabdruck, Iris)
Die meisten Anwendungen verwenden die erste Option, aber viele kombinieren mehrere davon, um das Sicherheitsniveau zu erhöhen. Dieses Konzept wird als Multi-Faktor-Authentifizierung (MFA) bezeichnet.
Ablauf der Authentifizierung
Der allgemeine Authentifizierungsablauf funktioniert folgendermaßen:
- Der Benutzer sendet sein Kennwort an den Server.
- Der Server verschlüsselt das Passwort und vergleicht es mit dem Passwort-Hash in der Datenbank.
- Wenn die Hashes übereinstimmen, erstellt der Server eine Sitzung und sendet das Sitzungs-Token an den Benutzer. Stimmen die Hashes hingegen nicht überein, wird eine Fehlermeldung ausgegeben.
- Der Benutzer verwendet dann das Sitzungs-Token bei jeder Anfrage. Bei jeder Anfrage überprüft der Server, ob das Token vorhanden und gültig ist.
Der obige Ablauf ist die so genannte Token-Authentifizierung. Andere Authentifizierungssysteme sind JSON Web Token(JWT), Basic Access Authentication, Social Login und so weiter.
Authentication vs. Authorization
Bei der Authentifizierung wird die Identität eines Benutzers überprüft, während bei der Autorisierung überprüft wird, ob ein Benutzer über ausreichende Berechtigungen zur Durchführung einer Aktion verfügt.
Zu den Autorisierungsmodellen gehören u. a. die obligatorische Zugriffskontrolle (MAC), die diskretionäre Zugriffskontrolle (DAC) und die rollenbasierte Autorisierung.
Vorteile der Authentifizierung
Sehen wir uns nun einige Vorteile der Authentifizierung in Ihren mobilen Anwendungen an.
Sicherheit
Die Authentifizierung kann Ihre App vor unbefugtem Zugriff schützen und sicherstellen, dass nur legitime Nutzer Zugang zu Ihrem Dienst haben.
Dies trägt dazu bei, Datenverletzungen und Cyberangriffe zu verhindern und Ihre App-Umgebung sicher und vertrauenswürdig zu halten.
Personalisierung
Die Authentifizierung ermöglicht eine personalisierte Benutzererfahrung innerhalb der App.
Wenn sich Benutzer anmelden, können sie auf individuelle Einstellungen, Präferenzen und Empfehlungen zugreifen, die auf ihre Bedürfnisse zugeschnitten sind.
Diese Personalisierung macht die App attraktiver und benutzerfreundlicher. Sie trägt dazu bei, die Benutzer durch ein relevanteres und angenehmeres Erlebnis zu binden.
Rechtliche Bestimmungen
In einigen Ländern ist es gesetzlich vorgeschrieben, dass Sie die Identität Ihrer Nutzer überprüfen müssen. Ein Beispiel dafür ist Know Your Customer (KYC).
Fast alle Finanzanwendungen sind dazu verpflichtet. Sie müssen über ein geeignetes Authentifizierungssystem verfügen, um diesen Vorschriften zu entsprechen oder die persönlichen Daten Ihrer Benutzer zu schützen.
Wie fügt man Authentifizierung zu einer React Native App hinzu?
Dieser Teil des Artikels bietet eine Schritt-für-Schritt-Anleitung zum Hinzufügen der Back4app Authentifizierung zu einer React Native (Expo) App.
Voraussetzungen
- Grundlegendes Verständnis von Backend as a Service (BaaS)
- JavaScript IDE, Node.js und ein mobiler Emulator oder ein physisches Gerät
- Fähigkeit, JavaScript-Code zu lesen und zu schreiben
- Erfahrung mit React Native und Expo
Ein kostenloses Back4app-Konto.
Was ist Back4app?
Back4app ist eine der besten Open-Source-Backend-as-a-Service-Lösungen (BaaS). Es ist eine ausgereifte und zuverlässige Plattform, die es seit 2015 gibt.
Zu ihren wichtigsten Funktionen gehören Echtzeit-Datenbanken, Cloud-Code-Funktionen, automatische RESTful/GraphQL-API-Generierung und vieles mehr!
Back4app verfügt über ein einfach zu bedienendes und intuitives Admin-Dashboard und eine Befehlszeilenschnittstelle (CLI) für fortgeschrittene Benutzer.
Außerdem bietet es SDKs für die gängigsten Programmiersprachen und Frameworks, wie JavaScript, PHP, Flutter und Dart.
Das Beste daran ist, dass Back4app eine kostenlose Version anbietet. Die kostenlose Version eignet sich hervorragend zum Testen und Prototyping und umfasst folgende Leistungen:
- 25k/Monatliche Anfragen
- 250 MB Datenspeicher
- 1 GB Datenübertragung
- 1 GB Dateispeicher
Warum Back4app verwenden?
- Unterstützt soziale Authentifizierung
- Bietet SDKs für die meisten Programmiersprachen und Frameworks
- Mühelose Einrichtung und Nutzung
- Ausgezeichneter Kundensupport
Um zu erfahren, wie die Back4app-Authentifizierung im Vergleich zur Firebase-Authentifizierung abschneidet, lesen Sie The Ultimate Guide to React Firebase Authentication.
Projekt-Einführung – Einstieg in die React Native-Authentifizierung
Wir werden eine produktionsreife React Native-Anwendung erstellen, die Back4app-Authentifizierung verwendet. Die Anwendung wird es Benutzern ermöglichen, sich zu registrieren, anzumelden und ihre Profile zu verwalten.
Darüber hinaus wird die Anwendung über zwei Tabs verfügen, einen für authentifizierte Benutzer und einen für nicht authentifizierte Benutzer.
Das Endprodukt wird in etwa so aussehen:
Fangen wir an zu programmieren!
Backend (Back4app)
In diesem Abschnitt erstellen wir eine Back4app-App, erweitern das Standard-Benutzermodell und erhalten die API-Schlüssel, die für die Verbindung mit dem Backend erforderlich sind.
App erstellen
Melden Sie sich zunächst bei Ihrem Back4app-Konto an oder erstellen Sie eines, wenn Sie noch keines haben.
Wenn Sie sich anmelden, werden Sie zu Ihrer App-Liste weitergeleitet. Klicken Sie auf „ Build new app“, um eine neue App zu erstellen.
Mit der Back4app-Plattform können Sie zwei Arten von Apps bereitstellen – entweder Backend as a Service (BaaS) oder Container as a Service (CaaS). Die Authentifizierung ist im BaaS enthalten, wählen Sie sie also aus.
Geben Sie Ihrer Anwendung einen beschreibenden Namen, wählen Sie als Datenbank NoSQL und klicken Sie auf „ Create “.
Warten Sie etwa zwei Minuten, bis die Plattform die App erstellt hat. Back4app kümmert sich um alles, von der Erstellung des App-Layers bis zur Einrichtung der Datenbank, der Sicherheit, der Skalierung und vielem mehr.
Sobald Sie fertig sind, werden Sie zur Datenbank-Schnittstelle weitergeleitet.
Datenbank modifizieren
Lassen Sie uns nun über die Datenbankklassen sprechen.
Jede Back4app-Datenbankklasse wird mit den folgenden Standardfeldern geliefert:
+-----------+------------+-----------------------------------------+
| Data type | Name | Description |
+-----------+------------+-----------------------------------------+
| String | objectId | Object's unique identifier |
+-----------+------------+-----------------------------------------+
| Date | createdAt | Date of object creation |
+-----------+------------+-----------------------------------------+
| Date | updatedAt | Date of object's last update |
+-----------+------------+-----------------------------------------+
| ACL | ACL | Access Control List (security features) |
+-----------+------------+-----------------------------------------+
Die Klasse User verfügt über einige zusätzliche Felder:
+-----------+----------------+--------------------------+----------+
| Data type | Name | Default value | Required |
+-----------+----------------+--------------------------+----------+
| String | username | | yes |
+-----------+----------------+--------------------------+----------+
| String | email | | no |
+-----------+----------------+--------------------------+----------+
| Boolean | emailVerified | false | no |
+-----------+----------------+--------------------------+----------+
| String | password | | yes |
+-----------+----------------+--------------------------+----------+
| Object* | authData | {} | yes |
+-----------+----------------+--------------------------+----------+
Die Standard-Back4app-Benutzerklasse sollte für die meisten Anwendungsfälle ausreichend sein. Dennoch ist es einfach, sie zu erweitern. Um zu demonstrieren, wie das geht, fügen wir ein Biographie-Feld (bio) hinzu.
Klicken Sie zunächst auf die Schaltfläche „+ Column“ oberhalb der Datenbanktabelle.
Im Formular zur Spaltenerstellung wählen Sie „String“ als Datentyp, setzen den Namen auf bio, machen ihn erforderlich und klicken auf „ Add“.
Gut, jetzt wissen Sie, wie die Back4app-Datenbankklassen funktionieren und wie Sie das Benutzermodell erweitern können.
API Key
Sie benötigen die API Key Ihrer App, um sich vom Frontend aus mit dem Backend zu verbinden.
Um diese zu erhalten, navigieren Sie zu Ihrer Back4app-App und wählen Sie „ Security & Keys “ in der Seitenleiste. Achten Sie auf den „Client key“ und den „JavaScript key“.
Gut, das war’s von der Backend-Seite.
Frontend (React Native)
In diesem Abschnitt werden wir eine Expo-App erstellen, eine Komponentenbibliothek installieren, die Navigation einrichten, uns um die Bildschirme kümmern und schließlich das Frontend mit dem Backend verbinden.
App erstellen
Um eine React Native-App zu erstellen, verwenden wir das Dienstprogramm create-expo-app. Dieses Dienstprogramm vereinfacht die Erstellung von React-Native-Apps, indem es die Verzeichnisstruktur erstellt, TypeScript konfiguriert usw.
Führen Sie zunächst die folgenden Befehle aus:
npx create-expo-app@latest back4app-expo-auth
cd back4app-expo-auth
Mit diesem Befehl wird auch create-expo-app installiert, falls Sie es noch nicht haben.
Sie werden feststellen, dass das Bootstrap-Projekt die folgende Verzeichnisstruktur hat:
back4app-expo-auth/
├── app - Layouts, screens
├── assets - Static assets (e.g. images, videos, fonts)
├── components - Reusable components used through the app
├── constants - Static variables & configurations
├── hooks - Custom React hooks
├── scripts - Development scripts
├── app.json - Expo configuration & metadata
├── expo-env.d.ts - Expo TypeScript declarations
├── ...
Starten Sie den Entwicklungsserver:
$ npx expo start
Drücken Sie abschließend A, um die App auf Ihrem Android-Emulator zu öffnen. Alternativ können Sie auch den iOS-Emulator oder ein physisches iOS-Gerät verwenden. Sobald die App geöffnet ist, sollten Sie den Standard-Expo-Bildschirm sehen.
React Native Paper
Um den UI-Entwicklungsprozess zu vereinfachen, werden wir React Native Paper verwenden.
React Native Paper ist eine einfach zu bedienende, hochwertige Komponentenbibliothek für React Native-Anwendungen. Sie bietet viele vorgefertigte Komponenten, die fast jeden Anwendungsfall abdecken.
Installieren Sie sie zunächst über NPM:
$ npm install react-native-paper react-native-safe-area-context
Wenn Sie für iOS entwickeln, müssen Sie auch die nativen Teile der Bibliothek einbinden:
npx pod-install
Als Nächstes konfigurieren Sie Babel so, dass unbenutzte Komponenten in der Produktion nicht eingebunden werden:
// babel.config.js
module.exports = function(api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
env: {
production: {
plugins: ["react-native-paper/babel"],
},
},
};
};
Navigieren Sie dann zu app/_layout.tsx und verpacken Sie die App in PaperProvider wie folgt:
// app/_layout.tsx
// ...
export default function RootLayout() {
// ...
return (
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
<PaperProvider>
<Stack>
<Stack.Screen name="index" options={{headerShown: false}}/>
<Stack.Screen name="(auth)" options={{headerShown: false}}/>
<Stack.Screen name="(tabs)" options={{headerShown: false}}/>
<Stack.Screen name="+not-found"/>
</Stack>
</PaperProvider>
</ThemeProvider>
);
}
Vergessen Sie nicht den Import am Anfang der Datei:
import {PaperProvider} from "react-native-paper";
Perfekt, wir haben die Komponentenbibliothek erfolgreich installiert.
Container
Ein weiterer Schritt ist die Erstellung einer Container Komponente. Diese Komponente wird in allen unseren Bildschirmen verwendet und fügt an allen Seiten einen Rand hinzu, damit der Inhalt nicht bis zum Rand des Bildschirms reicht.
Erstellen Sie eine Datei Container.tsx im components Ordner:
// components/Container.tsx
import React from "react";
import {View} from "react-native";
export type ContainerProps = {
children: React.ReactNode;
}
export function Container({children}: ContainerProps) {
return (
<View style={{margin: 12}}>
{children}
</View>
);
}
Wie in der Projekteinführung erwähnt, wird unsere App zwei Navigationsregisterkarten haben.
Eine ist für authentifizierte Benutzer und die andere für nicht authentifizierte Benutzer. Auf der authentifizierten Registerkarte können die Benutzer ihre Profile verwalten, auf der anderen können sie sich anmelden oder ein Konto erstellen.
Um dies zu erreichen, erstellen Sie zunächst die folgende Verzeichnisstruktur:
app/
├── (auth)/
│ ├── _layout.tsx
│ ├── login.tsx
│ └── register.tsx
├── (tabs)/
│ ├── _layout.tsx
│ └── profile.tsx
├── +html.tsx
├── +not-found.tsx
├── _layout.tsx
└── index.tsx
Weitere Informationen über Expo Router finden Sie in den offiziellen Dokumenten.
Expo-Layouts enthalten in der Regel eine Menge an Standardcode. Ich möchte den Artikel nicht mit Code überschwemmen, also holen Sie sich bitte den Inhalt der Datei von GitHub:
Fügen Sie Folgendes in index.tsx ein:
// app/index.tsx
import React, {useEffect} from "react";
import {ActivityIndicator} from "react-native-paper";
import {useRouter} from "expo-router";
import {View} from "react-native";
export default function IndexScreen() {
const router = useRouter();
const isAuthenticated = true;
useEffect(() => {
setTimeout(() => {
if (isAuthenticated) {
router.push("profile");
} else {
router.push("login");
}
}, 1000);
}, []);
return (
<View style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}>
<ActivityIndicator
size="large"
animating={true}
/>
</View>
);
}
Die Datei index.tsx ist der Einstiegspunkt der Anwendung. In ihr wird geprüft, ob der Benutzer authentifiziert ist, und dann entsprechend weitergeleitet. Im Moment basiert die Umleitung auf der Variable isAuthenticated
Dann nehmen Sie den Code für die Bildschirme:
Der Code für die Bildschirme ist ziemlich einfach. Es handelt sich um React Native Code, der React Native Paper verwendet, um die Formulare und andere UI zu erstellen. Es werden auch grundlegende React-Hooks wie useState() und useEffect() verwendet.
Parse SDK
Für die Verbindung mit dem Backend verwenden wir das Parse SDK. Das SDK bietet Methoden zur Datenspeicherung, Manipulation, Benutzerauthentifizierung und weitere Funktionen.
Installieren Sie es zunächst über NPM:
$ npm install parse @react-native-async-storage/async-storage --save
$ npm install --save-dev @types/parse
Wir haben auch das Paket @react-native-async-storage/async-storage installiert, um die Benutzersitzung zu erhalten, wenn die Anwendung geschlossen wird.
Ohne dieses Paket müssten sich die Benutzer jedes Mal, wenn sie die Anwendung öffnen, neu authentifizieren.
Erstellen Sie dann eine .env-Datei im Stammverzeichnis des Projekts wie folgt:
EXPO_PUBLIC_APPLICATION_ID=<your-back4app-application-id>
EXPO_PUBLIC_JAVASCRIPT_KEY=<your-back4app-client-key>
Ersetzen Sie <your-back4app-application-id>und <your-back4app-client-key> durch die API-Schlüssel, die Sie im Backend-Abschnitt des Artikels erhalten haben.
Initialisieren Sie Parse in _layout.tsx
wie folgt:
// app/_layout.tsx
// ...
import Parse from "parse/react-native.js";
import AsyncStorage from "@react-native-async-storage/async-storage";
import ParseContext from "@/context/parseContext";
Parse.setAsyncStorage(AsyncStorage);
Parse.initialize(
process.env.EXPO_PUBLIC_APPLICATION_ID ?? "",
process.env.EXPO_PUBLIC_JAVASCRIPT_KEY ?? "",
)
Parse.serverURL = "https://parseapi.back4app.com/";
async function testParse() {
try {
const testMessage = new Parse.Object("TestMessage");
testMessage.set("message", "Hello, World!");
await testMessage.save();
} catch (error) {
console.log("Error saving the test message: ", error);
}
}
testParse().then(() => console.log("Successfully connected to Parse!"));
// ...
Wir haben auch die Funktion testParse() eingebunden, die die Verbindung zu Back4app testet, indem sie eine „Hello, world!“-Nachricht zur Datenbank hinzufügt.
Stellen Sie sicher, dass die Verbindung funktioniert, indem Sie den Expo-Server neu starten und die Anwendung im Emulator ausführen.
Navigieren Sie zur Datenbankansicht Ihrer Anwendung und überprüfen Sie, ob Sie die Nachricht sehen können.
Wenn Sie die Fehlermeldung „Error: crypto.getRandomValues() not supported“ erhalten. Installieren Sie die folgenden Abhängigkeiten:
npm install react-native-get-random-values --save
npm i --save-dev @types/react-native-get-random-values
Fügen Sie dann den Import am Anfang von _layout.tsx hinzu (vor dem Import von Parse):
import "react-native-get-random-values";
Starten Sie den Entwicklungsserver neu; alles sollte gut funktionieren.
Um die Parse-Instanz in allen Bildschirmen verfügbar zu haben, werden wir sie mit React Context übergeben.
Erstellen Sie zunächst ein Context-Verzeichnis und legen Sie die folgende Datei parseContext.ts darin ab:
import {createContext} from "react";
const ParseContext = createContext<typeof Parse | null>(null);
export default ParseContext;
Dann verpacken Sie die gesamte App damit und übergeben die Parse-Instanz:
// app/_layout.tsx
// ...
return (
<ParseContext.Provider value={Parse}>
{/* ... */}
</ParseContext.Provider>
)
Datenabruf und -manipulation
In diesem letzten Abschnitt verwenden wir Parse SDK, um den Benutzer zu authentifizieren und Benutzerinformationen abzurufen.
Anstatt denselben Code in jedem Bildschirm zu wiederholen, erstellen wir einen useParse Hook. Dieser Hook holt die ParseInstanz aus dem Kontext, ruft die Benutzerinformationen ab und löst eine Aktualisierung aus, sobald alles fertig ist.
Erstellen Sie eine neue Datei namens useParse.ts im Ordner context:
// context/useParse.ts
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/context/parseContext";
export function useParse() {
const parse = useContext(ParseContext) as typeof Parse;
const [parseUser, setParseUser] = useState<Parse.User | null>(null);
const [isParseLoaded, setIsParseLoaded] = useState(false);
useEffect(() => {
(async () => {
try {
setParseUser(await parse.User.currentAsync());
} catch (e) {
console.error(e);
} finally {
setIsParseLoaded(true);
}
})();
}, []);
return {parse, parseUser, isParseLoaded};
}
Ändern Sie dann index.tsx und ersetzen Sie isAuthenticated durch eine tatsächliche Sitzungsprüfung:
// app/index.tsx
// ...
import {useParse} from "@/hooks/useParse";
export default function IndexScreen() {
const router = useRouter();
const {parse, parseUser, isParseLoaded} = useParse();
useEffect(() => {
if (!isParseLoaded) return;
(async () => {
if (parseUser) {
console.log("User is authenticated!");
console.log(parseUser.toJSON());
router.replace("/profile");
} else {
console.log("User is not authenticated.");
console.log({});
router.replace("/(auth)/login");
}
})();
}, [isParseLoaded]);
return (
// ...
);
}
Ändern Sie anschließend login.tsx, um den Benutzer anzumelden:
// app/(auth)/login.tsx
// ...
import {useParse} from "@/hooks/useParse";
export default function LoginScreen() {
const router = useRouter();
const {parse, parseUser, isParseLoaded} = useParse();
// ...
const onLogin = async () => {
// ...
try {
await parse.User.logIn(username, password);
router.push("/(tabs)/profile");
} catch (error: any) {
setError(error.message);
}
}
return (
// ...
);
}
Ändern Sie dann die register.tsx ähnlich wie login.tsx, aber ersetzen Sie diesmal das TODO wie folgt:
// app/(auth)/register.tsx
try {
const user = await parse.User.signUp(username, password, undefined, undefined);
user.setEmail(email);
await user.save();
router.replace("/(tabs)/profile")
} catch (error: any) {
setError(error.message);
}
Ändern Sie schließlich profile.tsx, um die Profilinformationen anzuzeigen:
// app/(tabs)/profile.tsx
// ...
import {useParse} from "@/hooks/useParse";
export default function IndexScreen() {
const router = useRouter();
const {parse, parseUser, isParseLoaded} = useParse();
// ...
useEffect(() => {
if (!parseUser) return;
setBio(parseUser.get("bio") || "");
}, [parseUser]);
const onSave = async () => {
if (!parseUser) return;
parseUser.set("bio", bio);
try {
await parseUser.save();
setSuccess("Bio saved successfully.");
} catch (error: any) {
setError(error.message);
}
}
const onLogout = async () => {
router.replace("/(auth)/login");
await parse.User.logOut();
}
return (
<Container>
{!isParseLoaded ? (
<ActivityIndicator
size="large"
animating={true}
/>
) : (
<>
{/* ... */}
</>
)}
</Container>
);
}
Denken Sie daran, die TODOs im Rückruf zu ändern. Verwenden Sie {parseUser!.getUsername()} und {parseUser!.getEmail()}.
Jetzt sollte die Anwendung voll funktionsfähig sein. Starten Sie den Entwicklungsserver neu und testen Sie ihn, indem Sie ein Konto erstellen, sich anmelden und abmelden und Ihre Bio ändern. Stellen Sie abschließend sicher, dass die Änderungen in der Datenbank übernommen werden.
Zusammenfassung
Abschließend wissen Sie nun, was Authentifizierung ist, welche Vorteile sie bietet und wie sie sich von der Autorisierung unterscheidet.
Außerdem haben Sie gelernt, wie Sie die Back4app-Authentifizierung einrichten und in eine React Native (Expo-basierte) Anwendung integrieren können.
Künftige Schritte
- Lernen Sie mehr über soziale Authentifizierung mit Google, Facebook und Apple
- Schauen Sie sich die Back4app Admin App für ein schickes Echtzeit-Administrationspanel an
Der endgültige Quellcode ist auf GitHub verfügbar.