Kako postaviti autentifikaciju korisnika pomoću React, Redux i Redux Saga

AŽURIRANJE (12.02.2019.): Nedavno sam ažurirao ovaj projekt najnovijim usmjerivačima za reakciju, tj. Verzijom 4.3.1, koji je reakcijski usmjerivač-dom. Idite u njegovo spremište kako biste pregledali promjene.

U svom prethodnom blogu napisao sam kako napisati skalabilnu arhitekturu u Node.js. Budući da sam koristio poštara da testiram rad te platforme, mislio sam da bi bilo dobro primijeniti klijentsku stranu. Da bih napisao svoju klijentsku stranu, odlučio sam se koristiti tehnološkim stogom u nastavku:

  • Reagirati
  • Redux
  • Redux-Saga
  • Reakcijski usmjerivač

Ovaj post pretpostavlja da već znate reakciju i osnovne koncepte Reduxa i Redux-Sage.

Početak rada

Kloniraj moje prethodno spremište blogova. CDu svoju korijensku mapu i pokrenite npm install. Ovo će instalirati sve ovisnosti.

Drugo, instalirajte mongodbu vašem stroju. Jednom instaliran pokrenite mongo poslužitelj pomoćumongodnaredbu na vašem terminalu, ako nije pokrenuta kao usluga na vašem stroju.

Zatim provjerite je li nodemon paket instaliran na vašem računalu globalno . Idite u mapu na strani poslužitelja i pokrenitenodemon index.jsza pokretanje pozadinskog poslužitelja.

Sad kad je naša pozadina pokrenuta, vrijeme je da uđemo u njezinu implementaciju na strani klijenta.

Ako još niste instalirali create-react-appzatim ga nastavite instalirati pomoću sljedeće naredbe.

npm install create-react-app -g

Ova naredba će se instalirati create-react-appglobalno .

Izradite projekt

Sada je vrijeme za stvaranje projekta. Koristiti:

create-react-app react-login

To će stvoriti novi projekt s imenom react-login. Samo naprijed i cdu tu mapu. Otvori svojpackage.jsondatoteku u omiljenom uređivaču i dodajte sljedeće ovisnosti:

Ne trebaju nam dodatna svojstva u ovoj package.jsondatoteci. Jednostavno ih možemo ukloniti, ali ostavit ću to kako jest i krenuti naprijed tako da dođemo do zanimljivog dijela ovog bloga.

Sada jednostavno pokrenite:

npm install

koji će instalirati sve ovisnosti koje smo gore spomenuli.

Indeksna datoteka

Za početak otvorite index.jsdatoteku i stavite donji kod u ovu datoteku.

U ovom kodu uvozimo reacti react-dom. Zatim uvozimo Routeri browserHistoryiz react-router. Oni su potrebni za svrhe usmjeravanja, koje ću koristiti kasnije uroutes/index.jsdatoteka. Dalje, uvozimo Provider, koristi se za pohranu podređenih komponenata.

configureStorei routesnešto su što ćemo sljedeće uvesti, a što ću primijeniti za sekundu. Samo ih uvezite kakve jesu i upotrijebite ih u ovoj datoteci kao što je gore prikazano.

Sada je postavljena naša indeksna datoteka.

Konfiguracija trgovine

Stvorite novu mapu pod nazivom storeunutar srcmapa. Unutar te nove mape stvorite datoteku pod nazivom configureStore.js,i zalijepite sljedeći kod u tu datoteku.

Prvo uvozimo createStore, na što ćemo se naviknuti createStorei applyMiddlewarekoji ćemo upotrijebiti primijeniti posredničke proizvode na našu trgovinu - u ovom slučaju sage, ali o tome ćemo kasnije na ovom blogu - iz redux.

Zatim uvozimo rootReducer- to ćemo stvoriti kasnije. Za sada ga jednostavno uvezite i koristite onakvog kakav jest. Nakon toga slijedi funkcija configureStorekoja vraća objekt pozivanjem createStorefunkcije i prosljeđivanjem rootReducerkao parametar.

Konačno, export configureStorečini configureStoredostupnim u index.jsdatoteci, napravljenoj ranije.

Sad nam to nije na putu, samo naprijed i stvorite src/reducersmapu, stvorite datoteku index.js i zalijepite donji kod u ovu datoteku.

Ova je datoteka odgovorna za uvoz ostataka reduktora u mapu reduktora, njihovo kombiniranje i izvoz, tako da su dostupni za upotrebu u configureStore.js. Izmijenit ćemo ovu datoteku kad kasnije na ovom blogu dodamo nove reduktore.

Datoteka za usmjeravanje

Vrijeme je za datoteku ruta. Samo naprijed i stvoritesrc/routesi unutar ove mape stvorite index.jsdatoteka. Sada ga otvorite i zalijepite donji kod.

Glavni cilj ove datoteke je upravljanje usmjeravanjem u našem projektu. Uvoz datoteka React, Routei IndexRoute. Nakon toga trebamo spremnik, u ovom slučaju ja uvozim container/App, što ćemo uskoro napisati. Sljedeće je RegisterPage, što je komponenta, a mi ćemo to također napisati.

U roditelju Route, kada se domaća staza podudara, onda jednostavno generiramo svoj Appspremnik. Na IndexRoutekorisnici će vidjeti RegisterPagešto će biti pružene unutar Appspremnika.

Spremnik

Sad je vrijeme za kontejner. Samo naprijed i napravite novu mapu pod nazivom container. Unutar ove mape stvorite novu datoteku pod nazivom App.jsi stavite donji kod u ovu datoteku.

Ovo je prilično jednostavno. Glavna svrha ove datoteke je prikazati ostale komponente.{this.props.children}služi u tu svrhu.

Registracija

Sad je vrijeme za registerPage. Stvorite novu mapusrc/componentsi stvorite komponentu unutar mape komponenata pod nazivomregisterPage.js. Zalijepite donji kod u ovu komponentu.

Za sada je ovo vrlo jednostavna komponenta. To ćemo urediti kasnije kako bismo dodali obrazac za registraciju i unijeli neke funkcije u njega.

Izlaz

Nakon stvaranja svih mapa i datoteka iznad, pokrenite npm startsvoj projekt i otvorite//localhost:3000u vašem pregledniku. Morali biste vidjeti donji rezultat.

Klikom na login ovdje će ne preusmjeriti na login put koji ćemo popraviti sljedeći.

Neka to uspije

Usmjeravanje

Da bi usmjeravanje funkcioniralo, prvo napravite novu komponentu unutar mape komponenata. Nazovite ga loginPage.jsi stavite donji kod unutar ove komponente.

Ova je komponenta vrlo jednostavna. Omogućuje osnovni sadržaj i poveznicu za registraciju komponente.

Sada otvorite routes.jsdatoteku koju smo već kreirali gore i napravite sljedeće promjene.

Promijenite indeksnu rutu u LoginPagejer želimo da korisnici slijeću na komponentu za prijavu kada posjete početnu stranicu. Prije nego što to učinite, uvezite ga iz mape komponenata.

Sada osvježite svoj preglednik i trebali biste moći loginPageprvo vidjeti . Kada kliknete na vezu "Registriraj se ovdje", registerPagetreba se prikazati.

Sada imamo osnovne rute koje rade.

Prijava i registracija

Registracija

Da bi postupak prijave funkcionirao, prvo ću voditi postupak registracije tako da u našu bazu podataka dodamo neke korisnike. Dakle, idemo naprijed i otvorimo ga components/registerPage.jsi ažuriramo donjim sadržajem.

Čini se da u ovoj datoteci sada ima puno koda, ali sve je jednostavno. Prvo uvozimoconnectpovezati našu storesregisterPagekomponenta. Zatim uvozimoregisterUserActionkoju ćemo sljedeće napisati.

Unutar renderfunkcije prvo provjeravam odgovor poslužitelja ako postoji, a zatim dodjeljujem uspjeh i svojstva poruka koja su primljena od poslužitelja. Ovo može biti zasebna funkcija, ali radi jednostavnosti stavio sam ih u renderfunkciju.

Slijedi obrazac za registraciju. Kad korisnik klikne na gumb za registraciju, aktivira onHandleRegistrationfunkciju koja iz obrasca dobiva unesene podatke korisnika idispatch registerUserActionsa svojim podacima kao parametrima. U sljedećem ćemo koraku napisati akcije.

Da bi gornji kod funkcionirao, trebamo mapStateToProps, kao što to činimo na dnu komponente, a zatim ga spojimo s registerPagekomponentom na kraju.

Akcije

Sada je vrijeme za dodavanje radnji. Samo naprijed i stvoritesrc/actionsmapu. Stvoriteindex.jsdatoteku i u nju smjestite donji kod.

Ovaj kôd izvozi neke konstante koje ćemo koristiti tijekom cijelog projekta.

Sada naprijed i stvorite authenticationActions.jsdatoteku u istoj mapi i u nju smjestite donji kod.

Ovdje uvozim datoteku indeksa koja izvozi konstante, a zatim export registrationUserActionvraćam objekt s vrstom radnje i korisničkim podacima. Vrsta akcije u ovom slučaju je REGISTER_USER. Ova će se radnja poslati kad se korisnik pokuša registrirati, a ona će biti dostupna tijekom cijelog našeg projekta koji ćemo slušati u našim sagama.

Sage

Sada smo u fazi kada možemo uvesti naše sage u naš projekt. Ako ste novi u Redux-Sagi, predlažem da prijeđite na ovaj blog prije nego što nastavite.

Ako već znate za sage, stvorite a src/sagasmapu. Stvoriteindex.jsdatoteku i u nju smjestite donji kod.

U gornjoj datoteci prvo uvozim forkiz effectsiwatchUserAuthenticationiz watchers- koji još ne postoji, ali mi ćemo sljedeću napraviti tu datoteku. Tada jednostavno izvozim funkciju generatora i račvam watchUserAuthentication.

Sada izvolite i stvorite watcher.jsdatoteku u istoj mapi kao gore i stavite donji kod u ovu datoteku.

Opet uvozim takeLatestefekt od redux-saga, pa registerSagaod authenticationSaga.js, koji ćemo stvoriti sljedeći. Zatim uvezite actions/index.jskao vrste.

Izvozim funkciju generatora koja u osnovi motri na REGISTER_USERakciju i upućuje poziv registerSaga.

Ajmo sada stvoriti authenticatioSaga.jssagu u istoj mapi kao gore, i stavimo donji kod u ovu datoteku.

U ovoj sagi uvozim još nekoliko efekata - puti to calliz redux-saga. Zatim registerUserServicese uvozi iz service/authenticationService.js. Uvozim sve radnje kao vrste iz actions/index.js. Tada izvozim funkciju generatora registerSaga.

Ova je funkcija odgovorna za pozivanje registerUserService, što upućuje ajax poziv našem poslužitelju radi registracije novog korisnika - što ću napisati nakon ovog koraka. Prima odgovor registerUserServicei pokreće REGISTER_USER_SUCCESSakciju. Ako postoji pogreška, tada se pokreće REGISTER_USER_ERRORradnja.

Uvezi sage

Sad kad imamo sage, vrijeme je da ih uvezemo u našu trgovinu. Otvorite store/configureStore.jsi ažurirajte njegov sadržaj sljedećim sadržajem.

Ovdje sam uvozi createSagaMiddleware, rootReduceri rootSaga. Zatim, unutar configureStorefunkcije, kreiram novu sagaMiddlewarei prosljeđujem je createStoreupotrebi applyMiddlewarefunkcije. Konačno, vodim rootSaga.

Sada je vrijeme za stvaranje src/servicesmape i stvaranje nove prve usluge. ImenujauthenticationService.jsi stavite donji kod u ovu uslugu.

Ova datoteka izvršava osnovni ajax zahtjev pomoću API-ja za dohvaćanje s nekim parametrima i zaglavljem. To je prilično sama po sebi objašnjenja usluga.

Reduktor

Sada kada upućujemo zahtjev poslužitelju, vrijeme je da primimo taj odgovor u našoj komponenti. Da bismo to učinili potreban nam je reduktor . Samo naprijed i stvorite areducers/registerReducer.jsdatoteku i u nju smjestite donji kod.

To je jednostavna funkcija reduktora koja dobiva stanje i vraća novo stanje. Provjerava REGISTER_USER_SUCCESSi REGISTER_USER_ERRORvrši radnje i vraća novo stanje komponenti.

Sada samo naprijed i otvorite src/reducers/index.jsdatoteku i ažurirajte je sljedećim sadržajem.

U ovome rootReducerću uvoziti sve reduktore, a zatim ih kombinirati prije izvoza. Upravo s tim radim register.

Pokretanje ažuriranog koda

Sad smo završili s postupkom registracije. Vrijeme je da osvježite svoj preglednik, prijeđete na rutu registracije i unesete neke podatke. Ako unesete postojeću e-poštu, trebali biste vidjeti donji rezultat.

Ako unesete novu e-poštu, trebali biste biti preusmjereni na loginPagešto ćemo sljedeće implementirati.

Prijaviti se

Vrijeme je da prijavimo korisnika nakon što se registrira. Samo naprijed i otvoricomponents/loginPage.jsdatoteku i ažurirajte je sljedećim sadržajem.

Ova je komponenta gotovo ista kao registerPage. Jedina je razlika što se otpremaloginUserActionkoje ćemo sljedeće napisati. Druga je razlika u tome što ću, ako odgovor poslužitelja bude uspješan, primiti JWT token. Pohranjujem taj žeton localStorage. Možete koristiti drugu metodu, ali u ovom primjeru koristim ovaj pristup.

Samo naprijed i otvori actions/authenticationActions.jsi ažurirajte ga sljedećim sadržajem.

Ovdje izvozim novu loginUserActionfunkciju s LOGIN_USERvrstom radnje i user payload.

Prije nego što krenete naprijed, otvorite actions/index.jsdatoteku i ažurirajte njezin sadržaj sljedećim.

Sada samo naprijed i otvorite sagas/watchers.jsdatoteku i ažurirajte njezin sadržaj sljedećim.

Evo, ja ga jednostavno uvozim loginSagai pozivam kad primiLOGIN_USERakcijski.

Još nemamo loginSaga. Iz tog razloga naprijed i otvoritesagas/authenticationSaga.jssagu i ažurirajte njezin sadržaj sljedećim.

Ovdje uvozim dodatnu uslugu - loginUserService, koju ću implementirati sljedeće -, a zatim izvozim novu imenovanu funkciju generatora loginSaga, koja radi gotovo isto što i registerSaga.

Sada otvorite services/authenticationService.jsuslugu i ažurirajte njezin sadržaj sljedećim.

Ovdje dodajem loginUserService koji čini gotovo isto što i registerUserService, tj. Šaljem ajax zahtjev za prijavu korisnika.

Sad kad smo uspješno poslali zahtjev poslužitelju, vrijeme je da od našeg poslužitelja primimo odgovor na našu komponentu za prijavu. Za to stvorite novi reduktor / loginReducer.js reduktor i u njega smjestite donji kod.

Čini gotovo istu stvar kao registerReducer- slušanje LOGIN_USER_SUCCESSi LOGIN_USER_ERRORdjelovanje i vraćanje novog stanja.

Sada otvorite reducers/index.jsdatoteku i ažurirajte njezin sadržaj donjim kodom.

Evo ga uvozim loginReduceri kombiniram s registerprije nego što ga vratim kao rootReducer.

Nakon toga osvježite svoj preglednik i unesite e-poštu koja još nije registrirana. Nakon pritiska gumba za prijavu trebali biste vidjeti donji rezultat.

Ako unesete registriranu e-poštu, zahtjev bi trebao biti uspješan, ali još ne biste trebali ništa vidjeti, jer nisam implementirao dashboardPagekomponenta. Ovome će se pristupiti tek nakon uspješne provjere autentičnosti. Rekavši to, provedimo to.

Stranica nadzorne ploče

Sada stvorite components/dashboardPage.jskomponentu i stavite donji kod u ovu komponentu.

Ovo je vrlo jednostavna komponenta - sve što treba jest vratiti Dashboardtekst.

Sada otvorite routes/index.jsrute i ažurirajte njen sadržaj na sljedeći način.

Evo radim neke nove stvari. Prvo uvozim dashboardPagei dodajem ga u route. Kadadashboardruti se pristupi requireAuthfunkcija će se aktivirati. Ova funkcija provjerava je li korisnik loggedInili nije. Da bih to provjerio, tražimtokenu localStorage, koji sam pohranio u loginPagekomponentu pri uspješnoj prijavi. Ako postoji, tada dashboardPagese prikazuje korisniku.

Kada osvježite stranicu u pregledniku, unesete registriranu e-poštu i pritisnete enter, trebali biste vidjeti dolje navedene rezultate.

Dakle, tu je, ovo je cjelovit sustav za prijavu koji koristi React, Redux i Redux-Saga. Ako želite vidjeti cijeli projekt, klonirajte ovo spremište.

Nadam se da vam se svidio ovaj post.