Implémentation de l’authentification utilisateur dans les applications React avec Appwrite —

L’authentification est le processus de vérification de l’identité d’un utilisateur avant d’accorder l’accès à une application. Il s’agit d’un aspect important du développement, car il protège non seulement les données de nos utilisateurs, mais améliore également l’expérience utilisateur globale. Nous pouvons également utiliser les détails vérifiés pour personnaliser l’expérience de notre utilisateur, fournir un contenu personnalisé et proposer des fonctionnalités telles que des paramètres spécifiques à l’utilisateur ou des préférences enregistrées.
Dans cet article, nous fournirons un guide étape par étape sur la façon d’authentifier les utilisateurs dans les applications React à l’aide d’Appwrite. Nous verrons également comment utiliser les fonctionnalités d’Appwrite pour implémenter les fonctionnalités de connexion et d’inscription, gérer les sessions utilisateur et les itinéraires protégés.
Qu’est-ce qu’Appwrite ?
Écriture d’application est une application gratuite et open source qui aide les développeurs à intégrer la technologie backend dans les applications Web. En tant que service backend, Appwrite offre différentes fonctionnalités d’authentification, allant de l’authentification multifacteur à la vérification et à la récupération de compte. Cela permet aux développeurs de mettre en œuvre plus facilement et de manière transparente une authentification sécurisée des utilisateurs.
Conditions préalables à la configuration d’Appwrite dans les projets React
Avant de suivre les étapes d’intégration d’Appwrite dans notre projet React, nous devons mettre en place les éléments suivants :
- Noeud.js installé sur notre appareil
- une compréhension de base de React et JavaScript
- un Écriture d’application compte (nous pouvons en créer un gratuitement)
1. Créez une application React
Ouvrez le terminal et exécutez la commande suivante :
npx create-react-app userauth
Accédez au répertoire du projet :
2. Choisissez une méthode d’installation Appwrite
Appwrite propose diverses options d’installation, nous permettant de choisir la méthode d’installation qui correspond le mieux à nos préférences. Voici quelques-unes des options disponibles pour installer Appwrite :
- Docker. Cette option exploite Docker pour simplifier la configuration et la gestion dans un environnement conteneurisé.
- Auto-hébergé. Cette option permet une installation directe sur notre serveur, offrant ainsi plus de contrôle mais nécessitant une configuration manuelle.
- Déploiement basé sur le cloud. Cela utilise un fournisseur de cloud pour les services gérés, l’évolutivité et une surcharge de configuration minimale.
- Interface de ligne de commande Appwrite. Cela fonctionne en installant Appwrite localement à des fins de développement et de test.
Pour cet article, nous utiliserons l’option de déploiement basée sur le cloud, car elle est relativement plus facile à configurer et offre une meilleure accessibilité aux utilisateurs.
3. Créez un projet Appwrite
Pour intégrer Appwrite dans notre application, nous devons être connectés à notre compte. Une fois connectés, nous pouvons suivre ces étapes :
- Créez un nouveau projet.
- Sélectionner
Application Web
comme plateforme. - Choisir
hôte local
en tant qu’hôte et nommez l’application. - Ouvrez un navigateur Web et accédez au tableau de bord.
Installation du SDK d’Appwrite dans l’application React
Pour intégrer Appwrite dans notre application React, nous devons installer le SDK JavaScript Appwrite. Nous pouvons le faire en suivant les étapes suivantes.
Tout d’abord, exécutez la commande suivante dans le répertoire racine du projet :
Ensuite, créez un fichier de configuration (Appwrite.js
) dans le src
dossier pour stocker le point de terminaison Appwrite et l’ID du projet.
import { Client, Account } from 'appwrite';
export const API_ENDPOINT = 'https://cloud.appwrite.io/v1'
export const PROJECT_ID = 'YOUR PROJECT ID HERE'
const client = new Client()
.setEndpoint(API_ENDPOINT)
.setProject(PROJECT_ID);
export const account = new Account(client);
export default client;
Remplacer les espaces réservés 'YOUR_APPWRITE_ENDPOINT'
et 'YOUR_APPWRITE_PROJECT_ID'
avec le point de terminaison Appwrite et l’ID du projet, qui peuvent être obtenus à partir du tableau de bord Appwrite.
Initialisez Appwrite dans notre application React. Dans notre principal index.js
ou App.js
fichier, importez et initialisez Appwrite à l’aide du fichier de configuration que nous avons créé précédemment :
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Appwrite } from 'appwrite';
import appwriteConfig from './appwrite';
const appwrite = new Appwrite();
appwrite.setEndpoint(appwriteConfig.endpoint).setProject(appwriteConfig.project);
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);`
Construire l’application principale
Une fois la configuration terminée, nous pouvons maintenant créer notre application. Dans cette application, nous aurons une logique de connexion, d’enregistrement et de déconnexion, qui utilisera les fonctionnalités de notre SDK Appwrite.
Implémentation de la fonctionnalité d’enregistrement
Pour permettre aux utilisateurs de créer des comptes et de s’inscrire dans notre application React, nous devons procéder comme suit.
Tout d’abord, nous créons un formulaire d’inscription. Le formulaire collectera les informations nécessaires, telles que l’e-mail et le mot de passe, et les enverra au serveur Appwrite pour la création de l’utilisateur :
return (
<div className="container">
<form ref={registerForm} onSubmit={handleRegistration}>
<div className="form-field-wrapper">
<label>Name:</label>
<input required type="text" name="name" placeholder="Enter name..." />
</div>
<div className="form-field-wrapper">
<label>Email:</label>
<input
required
type="email"
name="email"
placeholder="Enter email..."
/>
</div>
<div className="form-field-wrapper">
<label>Password:</label>
<input
type="password"
name="password1"
placeholder="Enter password..."
autoComplete="password1"
/>
</div>
<div className="form-field-wrapper">
<input type="submit" value="Register" className="btn" />
</div>
</form>
<p>{}</p>
</div>
);
Ensuite, nous devons créer une fonction qui effectue un appel API pour créer un nouvel utilisateur sur le serveur Appwrite à chaque fois que vous cliquez sur un bouton :
import React, { useRef } from "react";
import { ID } from "appwrite";
import { account } from "../appwrite";
const Register = () => {
const registerForm = useRef(null);
const handleRegistration = async (e) => {
e.preventDefault();
const name = registerForm.current.name.value;
const email = registerForm.current.email.value;
const password1 = registerForm.current.password1.value;
try {
const response = await account.create(
ID.unique(),
email,
password1,
name
);
console.log("Registration successful:", response);
} catch (error) {
console.error("Registration failed:", error);
}
};
return(
)
};
export default Register;
Dans cet extrait de code, nous créons un formulaire d’inscription qui accepte les entrées de l’utilisateur et les envoie au SDK Appwrite. Voici une description de la fonction qui gère l’enregistrement des utilisateurs.
- Définition de la fonction.
const handleRegistration = async (e) => { ... }
définit une fonction asynchrone nomméehandleRegistration
qui accepte un objet événement (e
) comme argument. - Empêcher l’envoi d’un formulaire par défaut.
e.preventDefault();
empêche le comportement par défaut de la soumission du formulaire, qui rechargerait généralement la page. Cela nous permet de gérer le processus d’inscription en utilisant JavaScript. - Tentative d’enregistrement. Nous utilisons le
try...catch
block pour gérer les erreurs potentielles pendant le processus d’enregistrement en implémentant la logique principale dans le bloc try et en détectant les erreurs potentielles dans le bloc catch. - Utilisation de la création de compte Appwrite. Dans
const response = await client.account.create(email, password);
nous appelons leaccount.create
méthode du client Appwrite que nous avons utilisée pour créer un nouveau compte utilisateur avec l’e-mail et le mot de passe fournis par l’utilisateur.await
suspend l’exécution de la fonction jusqu’à ce que l’appel d’API asynchrone soit terminé.client
fait référence à l’instance client Appwrite initialisée.
Une fois l’utilisateur enregistré, une nouvelle ligne qui stocke les détails de l’utilisateur est créée.
Implémentation de la fonctionnalité de connexion
Pour vous connecter à l’aide du SDK d’Appwrite, nous utilisons une fonction qui prend l’e-mail et le mot de passe de l’utilisateur comme paramètres et gère le processus d’authentification. Si les informations d’identification sont valides, le serveur renvoie un jeton d’authentification, que nous pouvons stocker dans le stockage côté client (comme le stockage local ou les cookies) pour les futurs appels d’API :
import React, { useRef } from "react";
import { ID } from "appwrite";
import { account } from "../appwrite";
const Login = () => {
const loginForm = useRef(null);
const handleLogin = async (e) => {
e.preventDefault();
const name = loginForm.current.name.value;
const email = loginForm.current.email.value;
const password1 = loginForm.current.password1.value;
try {
const response = await account.createEmailSession(email, password1);
console.log("User has been Logged In:", response);
} catch (error) {
console.error("Login failed:", error);
}
};
return (
<div className="container">
<form ref={loginForm} onSubmit={handleLogin}>
<div className="form-field-wrapper">
<label>Name:</label>
<input required type="text" name="name" placeholder="Enter name..." />
</div>
<div className="form-field-wrapper">
<label>Email:</label>
<input
required
type="email"
name="email"
placeholder="Enter email..."
/>
</div>
<div className="form-field-wrapper">
<label>Password:</label>
<input
type="password"
name="password1"
placeholder="Enter password..."
autoComplete="password1"
/>
</div>
<div className="form-field-wrapper">
<input type="submit" value="Login" className="btn" />
</div>
</form>
<p>{}</p>
</div>
);
};
export default Login;
Comme dans la logique d’enregistrement, nous créons un composant qui renvoie un formulaire. Ce formulaire accepte la saisie de l’utilisateur et l’envoie à une fonction qui vérifie les détails et connecte l’utilisateur s’il est autorisé.
Voici une description du code qui implémente la logique de connexion :
- Définition de la fonction. La première ligne du
handleLogin
fonctionconst handleLogin = async (e) => { ... }
définit une fonction asynchrone nomméehandleLogin
qui prend un objet événement (e
) comme entrée. Leasync
Le mot-clé montre qu’il utilise des promesses pour gérer les opérations asynchrones. Nous avons également utilisé lepreventDefault
méthode pour empêcher le comportement de soumission de formulaire par défaut du navigateur. - Appeler la création de session Appwrite.
const response = await client.account.createSession(email, password);
est utilisé pour appeler leaccount.createSession
qui crée une session et se connecte à l’utilisateur si les détails fournis correspondent aux détails enregistrés dans le stockage.
Création de pages protégées
Les pages protégées sont celles qui sont inaccessibles aux utilisateurs non authentifiés. Par exemple, nous avons une page de profil qui affiche les détails de l’utilisateur, mais nous souhaitons que cette page soit accessible aux utilisateurs connectés seuls. Pour y parvenir en utilisant Appwrite, nous devons d’abord créer une fonction qui assure le suivi de l’utilisateur authentifié. Cette fonction est créée sur une page distincte que nous connectons à d’autres pages nécessitant une vérification.
Création du hook d’authentification
Pour gérer l’authentification des utilisateurs et le suivi des sessions dans une application React, nous pouvons créer un hook personnalisé appelé useAuth
. Ce hook gardera une trace de la session de l’utilisateur authentifié et fournira les fonctions nécessaires pour vérifier l’état d’authentification :
import { createContext, useState, useEffect, useContext } from "react";
import { account } from "../appwrite";
import { useNavigate } from "react-router-dom";
import { ID } from "appwrite";
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const navigate = useNavigate();
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
useEffect(() => {
checkUserStatus();
}, []);
const checkUserStatus = async () => {
try {
const accountDetails = await account.get();
setUser(accountDetails);
} catch (error) {
console.error("Error checking user status:", error);
} finally {
setLoading(false);
}
};
const contextData = {
user,
loading,
};
return (
<AuthContext.Provider value={contextData}>
{loading ? <div>Loading...</div> : children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
return useContext(AuthContext);
};
export default AuthContext;
Dans le AuthProvider
composant, nous utilisons le useState
et useEffect
hooks pour garder une trace de l’état d’authentification de l’utilisateur. Nous initialisons également l’état d’authentification en récupérant les détails du compte à partir du SDK d’Appwrite. Le useAuth
le hook personnalisé permet à d’autres composants d’utiliser le contexte d’authentification, en fournissant un accès à l’utilisateur actuel et à l’état de chargement.
Création d’un itinéraire protégé distinct
Pour restreindre l’accès à certaines pages en fonction du statut d’authentification de l’utilisateur, nous avons besoin d’un composant ayant accès au hook que nous avons créé précédemment. Ce ProtectedRoute
Le composant vérifiera si l’utilisateur est authentifié et affichera la page prévue ou redirigera l’utilisateur vers la page de connexion s’il n’est pas authentifié :
import { Outlet, Navigate } from "react-router-dom";
import { useAuth } from "./useAuth";
const ProtectedRoute = () => {
const { user } = useAuth();
return user ? <Outlet /> : <Navigate to="/login" />;
};
export default ProtectedRoute;
Dans le ProtectedRoute
composant, nous utilisons le useAuth
hook pour vérifier si l’utilisateur est authentifié. Si l’utilisateur est authentifié, le children
(page prévue) sont rendus. Sinon, l’utilisateur est redirigé vers la page de connexion à l’aide du Navigate
composant de react-router-dom
.
Application de la protection aux pages prévues
Pour appliquer la protection aux pages prévues, nous pouvons utiliser le ProtectedRoute
composant dans notre configuration de routage dans le fichier JSX principal :
import "./App.css";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { AuthProvider } from "./utils/useAuth";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import Login from "./pages/login";
import Register from "../src/pages/registeration";
import NavBar from "./Components/NavBar";
import Logout from "./pages/Logout";
import ProtectedRoute from "./utils/ProtectedRoute";
function App() {
return (
<Router>
<AuthProvider>
<NavBar />
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/logout" element={<Logout />} />
<Route path="/register" element={<Register />} />
<Route path="https://www.sitepoint.com/" element={<Home />} />
<Route
path="/profile"
element={
<ProtectedRoute>
<Profile />
</ProtectedRoute>
}
/>
</Routes>
</AuthProvider>
</Router>
);
}
export default App;
Dans l’extrait de code précédent, nous utilisons le ProtectedRoute
composant pour envelopper le Home
composant. Cela en fait un enfant du ProtectedRoute
composants et veille à ce que le Home
Le composant n’est accessible qu’aux utilisateurs authentifiés.
Afficher les détails de l’utilisateur sur une page de profil
Lorsqu’un utilisateur a été authentifié, nous pouvons souhaiter afficher les détails de l’utilisateur, tels que son nom d’utilisateur, son adresse e-mail, sa photo de profil, etc. Cela peut également inclure l’affichage des informations sur son panier et sa liste de souhaits. Ceci peut être réalisé en récupérant les informations de l’utilisateur à partir du SDK d’Appwrite et en les restituant dans les composants React :
import React, { useState, useEffect } from 'react';
import appwrite from './appwrite';
function UserDetails() {
const [user, setUser] = useState(null);
useEffect(() => {
const fetchUserDetails = async () => {
try {
const response = await appwrite.account.get();
setUser(response);
} catch (error) {
console.error(error);
}
};
fetchUserDetails();
}, []);
return (
<div>
{user && (
<div>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
<img src={user.avatar} alt="User Avatar" />
</div>
)}
</div>
);
}
export default UserDetails;
Dans le code précédent, nous utilisons le useEffect
hook pour récupérer les détails de l’utilisateur lors du chargement du composant. Nous appelons également le appwrite.account.get()
méthode pour récupérer les informations de l’utilisateur et les stocker dans le user
État. Une fois les détails de l’utilisateur disponibles, nous pouvons afficher le nom et l’adresse e-mail de l’utilisateur dans le composant :
Création de la fonctionnalité de déconnexion
Pour implémenter la fonctionnalité de déconnexion, nous devons créer une fonction qui supprime la session utilisateur et efface les données de l’utilisateur actuel :
import React from "react";
import { Link } from "react-router-dom";
import { account } from "../appwrite";
import "./Logout.css";
function Logout() {
const logoutUser = async () => {
try {
const response = await account.deleteSession("current");
console.log("Logout successful:", response);
} catch (error) {
console.error("Logout failed:", error);
}
};
return (
<div className="logout-container">
<h2 className="logout-message">Are you sure you want to log out?</h2>
<div className="logout-options">
<p>
<Link to="https://www.sitepoint.com/" className="header-link">
No, I don't
</Link>
</p>
<p>
<button className="logout-button" onClick={logoutUser}>
Yes, I'm sure
</button>
</p>
</div>
</div>
);
}
export default Logout;
Dans le logoutUser
fonction, nous utilisons la account.deleteSession
méthode pour supprimer la session utilisateur actuelle, déconnectant ainsi l’utilisateur. Nous pouvons également effectuer un nettoyage supplémentaire, tel que la suppression des données utilisateur ou la réinitialisation de l’état de l’application.
Gestion des erreurs dans React et Appwrite
La création d’applications React robustes et conviviales nécessite une gestion efficace des erreurs, en particulier lors de l’utilisation de services backend comme Appwrite. En effet, l’expérience de l’utilisateur peut être facilement perturbée par un échec d’appel d’API, des erreurs réseau, une entrée utilisateur non valide ou un comportement inattendu du serveur. Voici quelques-unes des meilleures pratiques que nous pouvons utiliser pour gérer les erreurs avec élégance dans nos projets.
- Utiliser des blocs try/catch. Comme dans nos exemples précédents, utilisez
try/catch
bloque autour du code potentiellement sujet aux erreurs. Nous pouvons le faire en écrivant la logique prévue dans letry
bloquer et utiliser lecatch
bloquez pour gérer l’erreur de manière appropriée en affichant des messages informatifs, en enregistrant les détails ou en redirigeant les utilisateurs vers les pages pertinentes. - Limites d’erreur. Nous pouvons également utiliser les limites d’erreur de React pour obtenir des erreurs dans les composants enfants sans nécessairement affecter l’ensemble de l’application.
- Création de composants d’erreur personnalisés. La création de composants d’erreur dédiés qui affichent des messages conviviaux en fonction du type d’erreur rencontré permet d’offrir une expérience plus personnalisée et informative par rapport aux messages d’erreur génériques.
Conclusion
Choisir le bon système d’authentification fait partie intégrante de la création d’une application sécurisée. Par conséquent, il est extrêmement important de prendre en compte les exigences de notre application, le niveau de sécurité requis et l’expérience utilisateur que nous souhaitons offrir lors du choix des méthodes d’authentification pour notre application.
En suivant les étapes et les bonnes pratiques décrites dans cet article, nous pouvons implémenter un système d’authentification fiable et convivial dans nos applications React à l’aide d’Appwrite.
Source link