Project Templates
Social Network
Sistema di Autenticazione per il Tuo Network Sociale
53 min
introduzione in questo tutorial, imparerai come implementare un sistema di autenticazione completo per la tua applicazione web di social network utilizzando back4app come servizio backend costruirai funzionalità per la registrazione degli utenti, il login, il ripristino della password e la gestione delle sessioni caratteristiche critiche per qualsiasi applicazione sociale moderna back4app è una piattaforma backend as a service (baas) costruita su parse server che consente agli sviluppatori di creare applicazioni scalabili senza gestire l'infrastruttura del server le sue capacità di autenticazione degli utenti integrate la rendono perfetta per implementare rapidamente sistemi di gestione degli utenti sicuri entro la fine di questo tutorial, avrai creato un sistema di autenticazione completamente funzionale simile a quello utilizzato in back4gram, un'applicazione di social network implementerai la registrazione degli utenti con validazione, login sicuro, recupero della password e sessioni persistenti nell'applicazione, offrendo ai tuoi utenti un'esperienza fluida mantenendo i loro account sicuri progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app requisiti per completare questo tutorial, avrai bisogno di un account back4app puoi registrarti per un account gratuito su back4app com https //www back4app com un progetto back4app configurato puoi imparare a creare un nuovo progetto seguendo la nostra guida per iniziare con back4app https //www back4app com/docs/get started/welcome node js installato sulla tua macchina locale conoscenze di base di javascript, react js e concetti di api restful familiarità con i concetti moderni di sviluppo web (componenti, gestione dello stato, ecc ) passo 1 – comprendere il sistema di gestione degli utenti di back4app prima di immergersi nel codice, è importante comprendere come back4app gestisce la gestione degli utenti back4app è costruito su parse server, che fornisce una speciale parse user classe progettata specificamente per l'autenticazione la classe parse user la parse user classe in back4app estende l'oggetto standard di parse con funzionalità specializzate per l'autenticazione degli utenti include diversi campi incorporati nome utente un identificatore unico per l'utente (obbligatorio) password la password dell'utente (obbligatoria per la registrazione ma non memorizzata in forma recuperabile) email l'indirizzo email dell'utente (opzionale ma raccomandato) emailverificata un booleano che indica se l'utente ha verificato la propria email datiautenticazione dati di autenticazione per l'autenticazione di terze parti puoi anche aggiungere campi personalizzati per memorizzare informazioni aggiuntive sugli utenti, come foto del profilo, biografie o qualsiasi altro dato specifico dell'utente gestione delle sessioni quando un utente accede, back4app crea un token di sessione che identifica la sessione dell'utente questo token viene utilizzato per autenticare le richieste successive senza richiedere all'utente di accedere nuovamente il token di sessione è gestito automaticamente dal parse sdk ma può anche essere controllato manualmente se necessario ecco come funziona il flusso della sessione l'utente fornisce le credenziali (nome utente/email e password) back4app convalida le credenziali se valide, back4app crea un token di sessione il token è memorizzato localmente (tipicamente in localstorage o un meccanismo simile) il token è incluso nelle richieste api successive per autenticare l'utente vediamo come questo è implementato nell'applicazione back4gram il codice di inizializzazione di parse di solito appare così // initialize parse with your back4app credentials parse initialize("your app id", "your javascript key"); parse serverurl = "https //parseapi back4app com/"; questa configurazione nell'app back4gram consente a tutti i componenti di accedere al sdk di parse e di effettuare richieste autenticate una volta che un utente accede caratteristiche di sicurezza back4app fornisce diverse caratteristiche di sicurezza per la gestione degli utenti archiviazione sicura delle password le password non sono mai memorizzate in testo semplice, ma vengono automaticamente hashate e salate gestione delle sessioni le sessioni utente possono essere gestite e revocate tramite la dashboard di back4app liste di controllo degli accessi (acl) puoi controllare chi può leggere o scrivere oggetti specifici verifica dell'email back4app può inviare email di verifica agli utenti reimpostazione della password funzionalità integrata per reimpostazioni sicure delle password ora che comprendiamo le basi, passiamo alla configurazione del nostro progetto progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 2 – configurazione del tuo progetto per dimostrare come implementare l'autenticazione con back4app, creeremo una versione semplificata dell'applicazione di social network back4gram creare una nuova applicazione react per prima cosa, creiamo una nuova applicazione react apri il tuo terminale e esegui npx create react app social network auth cd social network auth installazione dei pacchetti richiesti successivamente, installeremo i pacchetti necessari npm install parse react router dom @chakra ui/react @emotion/react @emotion/styled framer motion questi pacchetti forniscono parse il sdk javascript per back4app react router dom per il routing delle pagine @chakra ui/react una libreria di componenti per costruire l'interfaccia utente struttura del progetto impostiamo una struttura di file di base per il nostro sistema di autenticazione src/ ├── components/ │ └── ui/ │ ├── field js │ └── toaster js ├── pages/ │ ├── signuppage js │ ├── loginpage js │ ├── resetpasswordpage js │ ├── profilepage js │ └── feedpage js ├── app js └── index js configurazione del parse sdk ora, iniziamo a inizializzare parse nella nostra applicazione crea un file chiamato src/parseconfig js import parse from 'parse/dist/parse min js'; // initialize parse parse initialize("your app id", "your javascript key"); parse serverurl = "https //parseapi back4app com/"; export default parse; sostituisci your app id e your javascript key con le credenziali del tuo progetto back4app puoi trovarle nel tuo dashboard di back4app sotto impostazioni app > sicurezza e chiavi successivamente, aggiorniamo src/index js per importare la nostra configurazione parse import react from 'react'; import reactdom from 'react dom/client'; import ' /index css'; import app from ' /app'; import ' /parseconfig'; const root = reactdom createroot(document getelementbyid('root')); root render( \<react strictmode> \<app /> \</react strictmode> ); impostazione delle rotte ora, impostiamo la struttura di routing di base in src/app js import react from 'react'; import { browserrouter as router, routes, route } from 'react router dom'; import {provider} from " /components/ui/provider"; // import pages import signuppage from ' /pages/signuppage'; import loginpage from ' /pages/loginpage'; import resetpasswordpage from ' /pages/resetpasswordpage'; import profilepage from ' /pages/profilepage'; import feedpage from ' /pages/feedpage'; function app() { return ( \<provider> \<router> \<routes> \<route path="/signup" element={\<signuppage />} /> \<route path="/login" element={\<loginpage />} /> \<route path="/reset password" element={\<resetpasswordpage />} /> \<route path="/profile" element={\<profilepage />} /> \<route path="/feed" element={\<feedpage />} /> \<route path="/" element={\<loginpage />} /> \</routes> \</router> \</provider> ); } export default app; creazione di componenti ui prima di iniziare a costruire le pagine di autenticazione, creiamo alcuni componenti ui riutilizzabili per prima cosa, creiamo src/components/ui/toaster js // a simple toast notification system export const toaster = { create ({ title, description, type }) => { alert(`${title} ${description}`); // in a real app, you would use chakra ui's toast system } }; quindi, crea src/components/ui/field js import react from 'react'; import { formcontrol, formlabel, formerrormessage, formhelpertext } from '@chakra ui/react'; export const field = ({ label, children, errortext, helpertext, rest }) => { return ( \<formcontrol isinvalid={!!errortext} { rest}> {label && \<formlabel>{label}\</formlabel>} {children} {errortext ? ( \<formerrormessage>{errortext}\</formerrormessage> ) helpertext ? ( \<formhelpertext>{helpertext}\</formhelpertext> ) null} \</formcontrol> ); }; ora siamo pronti per implementare il nostro sistema di autenticazione! progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 3 – creazione di un sistema di registrazione utenti iniziamo implementando la pagina di registrazione questa pagina permetterà ai nuovi utenti di creare un account fornendo un nome utente, un'email e una password crea un file chiamato src/pages/signuppage js import react, { usestate } from 'react'; import { usenavigate, link as routerlink } from 'react router dom'; import { box, button, heading, input, vstack, link, text, flex } from '@chakra ui/react'; import parse from 'parse/dist/parse min js'; import { toaster } from ' /components/ui/toaster'; import { field } from ' /components/ui/field'; function signuppage() { const \[username, setusername] = usestate(''); const \[email, setemail] = usestate(''); const \[password, setpassword] = usestate(''); const \[confirmpassword, setconfirmpassword] = usestate(''); const \[isloading, setisloading] = usestate(false); const \[showpassword, setshowpassword] = usestate(false); const \[errors, seterrors] = usestate({}); const navigate = usenavigate(); const validateform = () => { const newerrors = {}; if (!username trim()) { newerrors username = 'username is required'; } if (!email trim()) { newerrors email = 'email is required'; } else if (!/\s+@\s+\\ \s+/ test(email)) { newerrors email = 'email is invalid'; } if (!password) { newerrors password = 'password is required'; } else if (password length < 6) { newerrors password = 'password must be at least 6 characters'; } if (password !== confirmpassword) { newerrors confirmpassword = 'passwords do not match'; } seterrors(newerrors); return object keys(newerrors) length === 0; }; const handlesignup = async (e) => { e preventdefault(); if (!validateform()) { return; } setisloading(true); try { // create a new user using parse const user = new parse user(); user set('username', username); user set('email', email); user set('password', password); await user signup(); toaster create({ title 'success', description 'account created successfully!', type 'success', }); navigate('/feed'); } catch (error) { console error('error signing up ', error); toaster create({ title 'error', description error message, type 'error', }); } finally { setisloading(false); } }; return ( \<box maxw="400px" mx="auto" p={4}> \<vstack spacing={6} align="stretch"> \<heading textalign="center">create an account\</heading> \<form onsubmit={handlesignup}> \<vstack spacing={4} align="stretch"> \<field isinvalid={!!errors username}> \<field label>username\</field label> \<input type="text" value={username} onchange={(e) => setusername(e target value)} /> {errors username && ( \<field errortext>{errors username}\</field errortext> )} \</field> \<field isinvalid={!!errors email}> \<field label>email\</field label> \<input type="email" value={email} onchange={(e) => setemail(e target value)} /> {errors email && ( \<field errortext>{errors email}\</field errortext> )} \</field> \<field isinvalid={!!errors password}> \<field label>password\</field label> \<flex position="relative"> \<input type={showpassword ? 'text' 'password'} value={password} onchange={(e) => setpassword(e target value)} /> \<button aria label={showpassword ? 'hide password' 'show password'} size="xs" position="absolute" right="0 25rem" top="50%" transform="translatey( 50%)" onclick={() => setshowpassword(!showpassword)} zindex={2} \> {showpassword ? 'hide' 'show'} \</button> \</flex> {errors password && ( \<field errortext>{errors password}\</field errortext> )} \</field> \<field isinvalid={!!errors confirmpassword}> \<field label>confirm password\</field label> \<input type={showpassword ? 'text' 'password'} value={confirmpassword} onchange={(e) => setconfirmpassword(e target value)} /> {errors confirmpassword && ( \<field errortext>{errors confirmpassword}\</field errortext> )} \</field> \<button type="submit" colorscheme="blue" isloading={isloading} mt={2} \> sign up \</button> \</vstack> \</form> \<text textalign="center"> already have an account?{' '} \<link as={routerlink} to="/login" color="blue 400"> log in \</link> \</text> \</vstack> \</box> ); } export default signuppage; questo codice crea un modulo di registrazione con le seguenti caratteristiche validazione del modulo controlla che tutti i campi obbligatori siano compilati correttamente prima dell'invio attivazione della visibilità della password consente agli utenti di vedere cosa stanno digitando gestione degli errori mostra messaggi di errore appropriati per la validazione e i fallimenti della registrazione stato di caricamento mostra un indicatore di caricamento durante il processo di registrazione comprendere il processo di registrazione degli utenti di back4app la parte chiave di questo codice è la handlesignup funzione, che utilizza la classe parse user di back4app per creare un nuovo utente const user = new parse user(); user set('username', username); user set('email', email); user set('password', password); await user signup(); quando chiami signup() , back4app valida i dati forniti crittografa in modo sicuro la password crea un nuovo utente nel database crea e restituisce un token di sessione il token di sessione è automaticamente memorizzato dal parse sdk dopo una registrazione riuscita, l'utente viene automaticamente connesso, quindi possiamo reindirizzarlo direttamente alla pagina del feed nell'applicazione back4gram, questo è implementato in modo simile in signuppage js la principale differenza è che l'implementazione di back4gram utilizza componenti ui più avanzati e potrebbe includere campi aggiuntivi o logica di convalida con la funzionalità di registrazione completata, passiamo all'implementazione della funzionalità di accesso progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 4 – implementazione dell'accesso utente ora, creiamo la pagina di accesso che consentirà agli utenti di autenticarsi con le proprie credenziali crea un file chiamato src/pages/loginpage js import react, { usestate, useeffect } from 'react'; import { usenavigate, link as routerlink } from 'react router dom'; import { box, heading, input, button, text, vstack, link, } from '@chakra ui/react'; import parse from 'parse/dist/parse min js'; import { toaster } from ' /components/ui/toaster'; import { field } from ' /components/ui/field'; function loginpage() { const \[username, setusername] = usestate(''); const \[password, setpassword] = usestate(''); const \[isloading, setisloading] = usestate(false); const \[error, seterror] = usestate(''); const \[currentuser, setcurrentuser] = usestate(null); const navigate = usenavigate(); // check if a user is already logged in useeffect(() => { const checkcurrentuser = async () => { try { const user = await parse user current(); if (user) { setcurrentuser(user); navigate('/feed'); } } catch (error) { console error('error checking current user ', error); } }; checkcurrentuser(); }, \[navigate]); const handlelogin = async (e) => { e preventdefault(); if (!username || !password) { seterror('username and password are required'); return; } setisloading(true); try { // login with parse const loggedinuser = await parse user login(username, password); toaster create({ title 'login successful!', description `welcome back, ${loggedinuser getusername()}!`, type 'success', }); // redirect to feed after successful login navigate('/feed'); } catch (error) { toaster create({ title 'login failed', description error message, type 'error', }); seterror(error message); } finally { setisloading(false); } }; return ( \<box maxw="md" mx="auto" p={8} border="1px solid" bordercolor="gray 600" borderradius="md"> \<heading as="h1" size="xl" mb={6} textalign="center"> social network login \</heading> \<form onsubmit={handlelogin}> \<vstack spacing={4}> \<field label="username"> \<input type="text" value={username} onchange={(e) => setusername(e target value)} placeholder="your username" required /> \</field> \<field label="password" errortext={error} \> \<input type="password" value={password} onchange={(e) => setpassword(e target value)} placeholder="your password" required /> \</field> \<link as={routerlink} to="/reset password" alignself="flex end" fontsize="sm"> forgot password? \</link> \<button colorscheme="blue" width="full" type="submit" isloading={isloading} \> log in \</button> \</vstack> \</form> \<text textalign="center" mt={6}> don't have an account?{' '} \<link as={routerlink} to="/signup" color="blue 500"> sign up \</link> \</text> \</box> ); } export default loginpage; questa pagina di accesso ha le seguenti caratteristiche auto redirect se un utente è già connesso, viene reindirizzato automaticamente alla pagina del feed form validation garantisce che nome utente e password siano forniti prima dell'invio error handling mostra messaggi di errore appropriati per i tentativi di accesso non riusciti loading state mostra un indicatore di caricamento durante il processo di accesso password reset link fornisce un link alla pagina di reimpostazione della password comprendere il processo di accesso di back4app le parti chiave di questo codice sono controllo se esiste un utente loggato usando parse user current() accesso di un utente con parse user login(username, password) quando un utente accede con back4app le credenziali vengono inviate al server per la convalida se valide, viene generato e restituito un token di sessione il parse sdk memorizza automaticamente questo token l'oggetto utente viene restituito con i dati dell'utente corrente il token di sessione memorizzato viene quindi utilizzato automaticamente dal parse sdk per tutte le richieste successive, consentendo all'utente di rimanere loggato nell'applicazione back4gram, il sistema di accesso è implementato in modo simile in loginpage js , ma con componenti ui più avanzati e potenzialmente funzionalità aggiuntive come opzioni di accesso sociale ora passiamo all'implementazione della funzionalità di reset della password progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 5 – funzionalità di reset della password successivamente, creiamo la pagina di reimpostazione della password che consentirà agli utenti di recuperare i propri account se dimenticano le loro password crea un file chiamato src/pages/resetpasswordpage js import react, { usestate } from 'react'; import { link as routerlink } from 'react router dom'; import { box, heading, input, button, text, vstack, link, alert, alerticon, alerttitle, alertdescription, } from '@chakra ui/react'; import parse from 'parse/dist/parse min js'; import { toaster } from ' /components/ui/toaster'; import { field } from ' /components/ui/field'; function resetpasswordpage() { const \[email, setemail] = usestate(''); const \[isloading, setisloading] = usestate(false); const \[error, seterror] = usestate(''); const \[issuccess, setissuccess] = usestate(false); const handleresetpassword = async (e) => { e preventdefault(); if (!email) { seterror('email is required'); return; } // basic email validation const emailregex = /^\[^\s@]+@\[^\s@]+\\ \[^\s@]+$/; if (!emailregex test(email)) { seterror('invalid email format'); return; } setisloading(true); seterror(''); try { // request password reset await parse user requestpasswordreset(email); setissuccess(true); toaster create({ title 'email sent', description 'check your inbox for password reset instructions ', type 'success', }); } catch (error) { toaster create({ title 'reset request failed', description error message, type 'error', }); seterror(error message); } finally { setisloading(false); } }; return ( \<box maxw="md" mx="auto" p={8} border="1px solid" bordercolor="gray 600" borderradius="md"> \<heading as="h1" size="xl" mb={6} textalign="center"> reset password \</heading> {issuccess ? ( \<alert status="success" borderradius="md"> \<alerticon /> \<box> \<alerttitle>email sent successfully!\</alerttitle> \<alertdescription> check your inbox for password reset instructions \</alertdescription> \</box> \</alert> ) ( \<form onsubmit={handleresetpassword}> \<vstack spacing={4}> \<text> enter your email and we'll send you instructions to reset your password \</text> \<field label="email" errortext={error} \> \<input type="email" value={email} onchange={(e) => setemail(e target value)} placeholder="your email address" required /> \</field> \<button colorscheme="blue" width="full" type="submit" isloading={isloading} \> send instructions \</button> \<link as={routerlink} to="/login" color="blue 500"> back to login \</link> \</vstack> \</form> )} \</box> ); } export default resetpasswordpage; questa pagina di reimpostazione della password include validazione email garantisce che venga fornito un formato email valido stato di successo mostra un messaggio di successo dopo l'invio dell'email di reimpostazione gestione degli errori visualizza messaggi di errore appropriati se la richiesta di reimpostazione fallisce stato di caricamento mostra un indicatore di caricamento durante il processo di richiesta di reimpostazione comprendere il processo di reimpostazione della password di back4app la parte chiave di questo codice è l'utilizzo del parse user requestpasswordreset(email) metodo di back4app per inviare un'email di reimpostazione della password all'utente quando un utente richiede una reimpostazione della password con back4app back4app verifica che l'email esista nel database se l'email viene trovata, un'email di reimpostazione viene inviata all'utente l'email contiene un link con un token sicuro quando l'utente clicca sul link, viene indirizzato a una pagina di reimpostazione della password dopo aver impostato una nuova password, possono accedere con le loro nuove credenziali nell'applicazione back4gram, la funzionalità di reset della password è implementata in modo simile in resetpasswordpage js , utilizzando gli stessi metodi api di back4app ma potenzialmente con componenti ui più avanzati o funzionalità aggiuntive ora che abbiamo implementato le funzionalità di autenticazione di base, concentriamoci sulla gestione delle sessioni progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 6 – gestione e persistenza delle sessioni uno degli aspetti chiave di qualsiasi sistema di autenticazione è la corretta gestione delle sessioni questo assicura che gli utenti rimangano connessi mentre navigano nella tua applicazione e che le loro sessioni siano sicure creiamo una versione semplificata della pagina del feed per dimostrare il controllo e la gestione delle sessioni crea un file chiamato src/pages/feedpage js import react, { usestate, useeffect } from 'react'; import { usenavigate } from 'react router dom'; import { box, heading, button, text, vstack, hstack, spinner, center, } from '@chakra ui/react'; import parse from 'parse/dist/parse min js'; import { toaster } from ' /components/ui/toaster'; function feedpage() { const \[isloading, setisloading] = usestate(true); const \[currentuser, setcurrentuser] = usestate(null); const navigate = usenavigate(); // check if user is authenticated useeffect(() => { const checkauth = async () => { try { console log('checking authentication '); const user = await parse user current(); if (!user) { console log('no user found, redirecting to login'); navigate('/login'); return; } console log('user authenticated ', user id, user get('username')); setcurrentuser(user); setisloading(false); } catch (error) { console error('error checking authentication ', error); navigate('/login'); } }; checkauth(); }, \[navigate]); // function to handle logout const handlelogout = async () => { try { await parse user logout(); navigate('/login'); } catch (error) { console error('error logging out ', error); toaster create({ title 'error', description 'failed to log out please try again ', type 'error', }); } }; if (isloading) { return ( \<center h="100vh"> \<spinner size="xl" /> \</center> ); } return ( \<box maxw="800px" mx="auto" p={8}> \<hstack justify="space between" mb={8}> \<heading>social network feed\</heading> \<hstack> \<text>welcome, {currentuser get('username')}\</text> \<button onclick={handlelogout} colorscheme="red" variant="outline"> log out \</button> \</hstack> \</hstack> \<vstack align="stretch" spacing={4}> \<box p={4} borderwidth={1} borderradius="md"> \<text>this is your feed when authenticated with back4app, you'll see content here \</text> \<text mt={2}>your user id {currentuser id}\</text> \<text>your email {currentuser get('email')}\</text> \</box> \</vstack> \</box> ); } export default feedpage; questa pagina del feed implementa controllo dell'autenticazione verifica che l'utente sia connesso prima di mostrare il contenuto reindirizzamento automatico reindirizza alla pagina di accesso se non viene trovata alcuna sessione utente funzionalità di disconnessione consente all'utente di disconnettersi e di cancellare la propria sessione visualizzazione delle informazioni utente mostra informazioni sull'utente attualmente connesso comprendere la gestione delle sessioni di back4app back4app gestisce le sessioni in diversi modi archiviazione automatica della sessione il parse sdk archivia automaticamente il token di sessione dopo il login accesso all'utente corrente puoi accedere all'utente corrente con parse user current() scadenza della sessione le sessioni scadono tipicamente dopo un periodo stabilito (configurabile in back4app) disconnettersi puoi terminare una sessione con parse user logout() in un'applicazione di produzione come back4gram, la gestione delle sessioni è spesso più complessa nel file messagespage js di back4gram, possiamo vedere come viene controllata l'autenticazione all'inizio del componente useeffect(() => { const checkauth = async () => { try { console log('checking authentication '); const user = await parse user current(); if (!user) { console log('no user found, redirecting to login'); navigate('/login'); return; } console log('user authenticated ', user id, user get('username')); setcurrentuser(user); fetchconversations(user); } catch (error) { console error('error checking authentication ', error); navigate('/login'); } }; checkauth(); // clean up subscriptions when component unmounts // }, \[navigate]); questo schema di controllo dell'autenticazione a livello di componente è comune nelle applicazioni react che utilizzano back4app considerazioni sulla sicurezza delle sessioni quando si implementa la gestione delle sessioni con back4app, considera queste pratiche di sicurezza invalidazione automatica della sessione configura back4app per invalidare le sessioni dopo un certo periodo di inattività archiviazione sicura assicurati che i token di sessione siano archiviati in modo sicuro (il parse sdk gestisce questo automaticamente) solo https usa sempre https per prevenire l'intercettazione dei token di sessione disconnessione in azioni sensibili richiedi una nuova autenticazione per operazioni sensibili come la modifica delle password vediamo ora come implementare la gestione del profilo per completare il nostro sistema di autenticazione progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 7 – aggiunta della gestione del profilo utente l'ultimo pezzo del nostro sistema di autenticazione è la gestione del profilo utente questo consente agli utenti di visualizzare e aggiornare le informazioni del proprio profilo crea un file chiamato src/pages/profilepage js import react, { usestate, useeffect } from 'react'; import { usenavigate } from 'react router dom'; import { box, button, heading, text, vstack, hstack, input, textarea, avatar, formcontrol, formlabel, spinner, center, } from '@chakra ui/react'; import parse from 'parse/dist/parse min js'; import { toaster } from ' /components/ui/toaster'; import { field } from ' /components/ui/field'; function profilepage() { const \[user, setuser] = usestate(null); const \[username, setusername] = usestate(''); const \[email, setemail] = usestate(''); const \[bio, setbio] = usestate(''); const \[isloading, setisloading] = usestate(true); const \[isupdating, setisupdating] = usestate(false); const \[selectedfile, setselectedfile] = usestate(null); const \[avatarurl, setavatarurl] = usestate(null); const navigate = usenavigate(); // fetch user data useeffect(() => { const fetchuserdata = async () => { try { const currentuser = await parse user current(); if (!currentuser) { navigate('/login'); return; } setuser(currentuser); setusername(currentuser get('username') || ''); setemail(currentuser get('email') || ''); setbio(currentuser get('bio') || ''); // get avatar if available const avatar = currentuser get('avatar'); if (avatar) { setavatarurl(avatar url()); } setisloading(false); } catch (error) { console error('error fetching user data ', error); toaster create({ title 'error', description 'failed to load profile data', type 'error', }); navigate('/login'); } }; fetchuserdata(); }, \[navigate]); // handle profile update const handleupdateprofile = async (e) => { e preventdefault(); setisupdating(true); try { if (!user) return; user set('username', username); user set('email', email); user set('bio', bio); // handle avatar upload if a file is selected if (selectedfile) { const parsefile = new parse file(selectedfile name, selectedfile); await parsefile save(); user set('avatar', parsefile); setavatarurl(parsefile url()); } await user save(); toaster create({ title 'success', description 'profile updated successfully', type 'success', }); } catch (error) { console error('error updating profile ', error); toaster create({ title 'error', description error message, type 'error', }); } finally { setisupdating(false); } }; // handle avatar selection const handlefilechange = (e) => { if (e target files && e target files\[0]) { setselectedfile(e target files\[0]); // create a preview url const previewurl = url createobjecturl(e target files\[0]); setavatarurl(previewurl); } }; // handle logout const handlelogout = async () => { try { await parse user logout(); navigate('/login'); } catch (error) { console error('error logging out ', error); } }; if (isloading) { return ( \<center h="100vh"> \<spinner size="xl" /> \</center> ); } return ( \<box maxw="800px" mx="auto" p={8}> \<hstack justify="space between" mb={8}> \<heading>your profile\</heading> \<button onclick={handlelogout} colorscheme="red" variant="outline"> log out \</button> \</hstack> \<box p={8} borderwidth={1} borderradius="md"> \<form onsubmit={handleupdateprofile}> \<vstack spacing={6} align="start"> \<hstack spacing={8} w="full" align="start"> \<vstack align="center" minw="150px"> \<avatar size="2xl" src={avatarurl} name={username} mb={4} /> \<formcontrol> \<formlabel htmlfor="avatar upload" cursor="pointer" textalign="center"> \<button as="span" size="sm"> change avatar \</button> \<input id="avatar upload" type="file" accept="image/ " onchange={handlefilechange} display="none" /> \</formlabel> \</formcontrol> \</vstack> \<vstack spacing={4} flex="1"> \<field label="username" w="full"> \<input value={username} onchange={(e) => setusername(e target value)} /> \</field> \<field label="email" w="full"> \<input type="email" value={email} onchange={(e) => setemail(e target value)} /> \</field> \<field label="bio" w="full"> \<textarea value={bio} onchange={(e) => setbio(e target value)} placeholder="tell us about yourself" rows={4} /> \</field> \</vstack> \</hstack> \<button type="submit" colorscheme="blue" isloading={isupdating} alignself="flex end" \> save changes \</button> \</vstack> \</form> \</box> \</box> ); } export default profilepage; this profile page provides users with the ability to 1\ view profile information see their username, email, and bio 2\ update profile details change their username, email, and bio 3\ upload a profile picture select and upload a profile image 4\ log out end their session and return to the login page \### understanding back4app's user data management let's examine the key aspects of how back4app handles user data management \#### file uploads with parse file one powerful feature of back4app is the ability to easily handle file uploads using `parse file` ```javascript if (selectedfile) { const parsefile = new parse file(selectedfile name, selectedfile); await parsefile save(); user set('avatar', parsefile); setavatarurl(parsefile url()); } quando crei un nuovo parse file , back4app prende il tuo file (immagine, documento, ecc ) lo carica in uno storage sicuro restituisce un riferimento che può essere memorizzato con il tuo oggetto utente rende il file accessibile tramite un url aggiunta di campi utente personalizzati la classe parse user di back4app può essere estesa con campi personalizzati oltre a quelli predefiniti nel nostro esempio, abbiamo aggiunto bio un campo di testo per le descrizioni degli utenti avatar un campo file per le foto del profilo puoi aggiungere tutti i campi personalizzati di cui hai bisogno per i profili utente della tua applicazione user set('bio', bio); nell'applicazione back4gram, il profilepage js implementa funzionalità simili ma con più caratteristiche e un'interfaccia utente più complessa include campi aggiuntivi come conteggi dei follower, statistiche dei post e una gestione delle immagini più robusta progetto back4gram trova qui il codice completo per un progetto campione di social network costruito con back4app passo 8 – testare e sicurezza del tuo sistema di autenticazione ora che abbiamo costruito il nostro sistema di autenticazione, discutiamo su come testarlo e metterlo in sicurezza correttamente testare i flussi di autenticazione quando testi il tuo sistema di autenticazione, dovresti verificare ciascuno di questi flussi registrazione utente testa che gli utenti possano creare account con credenziali valide validazione input verifica che appaiano errori appropriati per input non validi processo di login assicurati che gli utenti possano accedere con credenziali corrette login fallito controlla che appaiano errori appropriati per credenziali errate reset della password conferma che il flusso di reset della password funzioni end to end persistenza della sessione verifica che gli utenti rimangano connessi tra le visite alle pagine processo di logout assicurati che gli utenti possano disconnettersi correttamente e che le sessioni siano terminate vulnerabilità di sicurezza comuni da evitare quando si costruiscono sistemi di autenticazione, sii consapevole di questi problemi di sicurezza comuni archiviazione delle password non memorizzare mai le password in testo semplice back4app gestisce questo automaticamente per te attacchi brute force implementa il rate limiting per i tentativi di accesso back4app fornisce questa funzionalità cross site scripting (xss) sanitizza gli input degli utenti per prevenire l'iniezione di script cross site request forgery (csrf) usa token appropriati per verificare l'autenticità delle richieste riferimenti diretti a oggetti insicuri non esporre id o riferimenti sensibili negli url migliori pratiche di sicurezza di back4app back4app fornisce diverse funzionalità di sicurezza che dovresti sfruttare 1 permessi a livello di classe (clp) nel tuo dashboard di back4app, puoi impostare i permessi a livello di classe per controllare chi può leggere, scrivere e eliminare oggetti vai al tuo dashboard di back4app naviga su database → browser clicca sul pulsante "sicurezza" per la tua classe utente configura i permessi in modo appropriato \[immagine schermata dei permessi a livello di classe di back4app che mostra le impostazioni di sicurezza della classe utente] per la classe utente, le impostazioni tipiche includono accesso in lettura pubblico solo per campi specifici (nome utente, avatar) nessun accesso pubblico in scrittura o eliminazione solo gli utenti autenticati possono aggiornare i propri record 2 liste di controllo degli accessi (acl) per oggetti individuali, puoi utilizzare le acl per controllare l'accesso // set an acl that only allows the current user to read and write this object const useracl = new parse acl(parse user current()); userobject setacl(useracl); await userobject save(); questo garantisce che solo l'utente che ha creato un oggetto possa accedervi o modificarlo 3 utilizzo della chiave master back4app fornisce una chiave master che bypassa i controlli di sicurezza non esporla mai nel codice lato client // never do this in client side code parse cloud usemasterkey(); // this should only be used in cloud code invece, per operazioni che richiedono privilegi elevati, utilizza le funzioni cloud 4 verifica email abilita la verifica email nelle impostazioni di back4app per garantire che gli utenti forniscano indirizzi email validi vai al tuo dashboard di back4app naviga su impostazioni app → impostazioni email configura il tuo adattatore email abilita la verifica email \[immagine schermata di configurazione delle impostazioni email di back4app] 5 autenticazione a due fattori per ulteriore sicurezza, puoi implementare l'autenticazione a due fattori utilizzando le funzioni cloud di back4app questo richiede che gli utenti forniscano una seconda forma di verifica (tipicamente un codice inviato al loro telefono o email) quando accedono implementazione del limite di richiesta per proteggerti dagli attacchi di forza bruta, puoi implementare il limite di richiesta utilizzando le funzioni cloud // cloud function to handle login with rate limiting parse cloud define("securelogin", async (request) => { const { username, password } = request params; // check for too many failed attempts const query = new parse query("loginattempt"); query equalto("username", username); query greaterthan("createdat", new date(date now() 15 60 1000)); // last 15 minutes const attempts = await query count(); if (attempts >= 5) { throw new error("too many login attempts please try again later "); } try { // attempt to log in const user = await parse user login(username, password); return { success true, user user tojson() }; } catch (error) { // record failed attempt const loginattempt = parse object extend("loginattempt"); const attempt = new loginattempt(); attempt set("username", username); await attempt save(null, { usemasterkey true }); throw error; } }); conclusione in questo tutorial, hai costruito un sistema di autenticazione completo per un'applicazione di social network utilizzando back4app hai implementato la registrazione degli utenti, il login, il ripristino della password e le funzionalità di gestione del profilo, tutte alimentate dalle capacità di gestione degli utenti integrate di back4app rivediamo ciò che hai imparato sistema di gestione degli utenti di back4app hai imparato come il parse server di back4app fornisce autenticazione degli utenti integrata con la parse user classe registrazione degli utenti hai implementato un modulo di registrazione che crea nuovi account utente nel database di back4app accesso degli utenti hai creato un sistema di accesso che autentica gli utenti e gestisce le sessioni ripristino della password hai aggiunto una funzionalità di ripristino della password sicura che invia email di recupero gestione delle sessioni hai imparato come mantenere le sessioni utente e proteggere le rotte gestione del profilo hai costruito una pagina del profilo che consente agli utenti di aggiornare le proprie informazioni e caricare foto del profilo migliori pratiche di sicurezza hai esplorato come proteggere il tuo sistema di autenticazione utilizzando le funzionalità di sicurezza di back4app con back4app, sei stato in grado di concentrarti sulla creazione di una grande esperienza utente piuttosto che sulla costruzione di un'infrastruttura backend complessa il parse server che alimenta back4app ha fornito tutte le api di autenticazione necessarie, garantendo anche che i dati degli utenti rimanessero sicuri il sistema di autenticazione che hai costruito forma la base della tua applicazione di social network con questo in atto, puoi ora espandere la tua applicazione aggiungendo funzionalità come post, commenti, mi piace e messaggi diretti, tutto utilizzando back4app come servizio backend prossimi passi integrazione del login sociale aggiungi il login con google, facebook o altri provider utilizzando le capacità oauth di back4app sicurezza migliorata implementa l'autenticazione a due fattori per una maggiore sicurezza ruoli utente configura il controllo degli accessi basato sui ruoli per diversi tipi di utenti funzionalità in tempo reale aggiungi messaggistica e notifiche in tempo reale utilizzando la live query di back4app per il codice completo dell'applicazione di social network back4gram, puoi controllare il repository github https //github com/templates back4app/back4gram i potenti servizi backend di back4app e l'integrazione con parse server lo rendono un'ottima scelta per costruire applicazioni di social network sicure e scalabili sfruttando le sue capacità di gestione degli utenti integrate, puoi creare un sistema di autenticazione robusto con il minimo sforzo, permettendoti di concentrarti sulla creazione di funzionalità uniche che rendono la tua applicazione distintiva