Sådan konfigureres brugergodkendelse ved hjælp af React, Redux og Redux Saga

OPDATERING (12.02.2019): Jeg opdaterede for nylig dette projekt med de seneste reageringsroutere, dvs. version 4.3.1, som er reaktor-router-dom. Gå til dets lager for at se ændringerne.

I min tidligere blog skrev jeg, hvordan man skriver en skalerbar arkitektur i Node.js. Da jeg brugte postbud til at teste, hvordan platformen fungerer, troede jeg, det ville være en god ide at implementere dens klientside. For at skrive klientsiden besluttede jeg at bruge nedenstående tech stack:

  • Reagere
  • Redux
  • Redux-Saga
  • Reager router

Dette indlæg antager, at du allerede kender reagerer og grundlæggende begreber i Redux og Redux-Saga.

Kom godt i gang

Klon mit tidligere blogopbevaringssted. CDind i rodmappen og kør npm install. Dette installerer alle afhængigheder.

For det andet skal du installere mongodbi din maskine. Når det er installeret, kør mongo-serveren ved hjælp afmongodkommando i din terminal, hvis den ikke startes som en tjeneste i din maskine.

Sørg derefter for, at nodemon-pakken er installeret på din maskine globalt . Gå til serversidemappen og kørnodemon index.jsfor at køre backend-serveren.

Nu hvor vores backend er i gang, er det tid til at komme ind på implementeringen af ​​klientsiden.

Hvis du endnu ikke har installeret create-react-appderefter gå videre installere det ved hjælp af følgende kommando.

npm install create-react-app -g

Denne kommando installeres create-react-appglobalt .

Opret projektet

Nu er det tid til at oprette et projekt. Brug:

create-react-app react-login

Dette opretter et nyt projekt med navnet react-login. Gå videre og cdind i den mappe. Åben dinpackage.jsonfil i din foretrukne editor og tilføj følgende afhængigheder:

Vi har ikke brug for yderligere egenskaber i denne package.jsonfil. Vi kan simpelthen fjerne dem, men jeg vil lade det være som det er og gå videre, så vi kommer til en interessant del i denne blog.

Kør nu bare:

npm install

som vil installere alle de afhængigheder, vi nævnte ovenfor.

Indeksfil

Start med at åbne index.jsfil, og placer koden nedenfor i denne fil.

I denne kode importerer vi reactog react-dom. Så importerer vi Routerog browserHistoryfra react-router. Disse kræves til routingformål, som jeg vil bruge senere iroutes/index.jsfil. Dernæst importerer vi Provider, dette bruges til at levere underlag til underordnede komponenter.

configureStoreog routeser noget, vi skal importere næste gang, og som jeg vil implementere om et sekund. Bare importer dem, som de er, og brug dem i denne fil som vist ovenfor.

Nu er vores indeksfil oprettet.

Gem konfiguration

Opret en ny mappe kaldet storeinde i srcfolder. Inde i den nye mappe skal du oprette en fil, der hedder configureStore.js,og indsæt følgende kode i den fil.

Først importerer vi createStore, som vil være vant til createStore, og applyMiddlewaresom vil blive brugt til at anvende mellemprodukter til vores butik - sagaer i dette tilfælde, men vi kommer ind på det senere i denne blog - fra redux.

Vi importerer derefter rootReducer- vi skal oprette dette senere. Indtil videre skal du blot importere det og bruge det som det er. Dette efterfølges af funktionen configureStore, som returnerer et objekt ved at kalde createStorefunktionen og passere rootReducersom parameter.

Endelig export configureStoregør configureStoretilgængelig i index.jsfilen, konstrueret tidligere.

Nu er det ikke i vejen, gå videre og opret src/reducersmappe, opret index.js- fil og indsæt koden nedenfor i denne fil.

Denne fil er ansvarlig for at importere resten af ​​reduceringerne i reduceringsmappen, kombinere dem og eksportere dem, så de er tilgængelige til brug i configureStore.js. Vi foretager ændringer i denne fil, når vi tilføjer nye reduktioner senere i denne blog.

Routing-fil

Tid til rutefilen. Gå videre og opretsrc/routesmappe og inde i denne mappe oprette en index.jsfil. Åbn det nu, og indsæt nedenstående kode.

Hovedmålet med denne fil er at håndtere routing i vores projekt. Import Filen React, Routeog IndexRoute. Derefter har vi brug for en container, i dette tilfælde importerer jeg container/App, som vi snart vil skrive. Næste er RegisterPage, hvilket er en komponent, og det skriver vi også.

I forældren Route, når hjemmestien matcher, gengiver vi simpelthen vores Appcontainer. På IndexRoutebrugerne vil se, RegisterPagehvilke der vil blive gengivet inde i Appcontaineren.

Beholder

Nu er det tid til containeren. Fortsæt og lav en ny mappe kaldet container. Inde i denne mappe skal du oprette en ny fil, der kaldes, App.jsog placere nedenstående kode i denne fil.

Dette er ret ligetil. Hovedformålet med denne fil er at gengive resten af ​​komponenterne.{this.props.children}tjener dette formål.

Registrering

Nu er det tid til registerPage. Opret en ny mappesrc/componentsog opret en komponent inde i komponentmappen, der kaldesregisterPage.js. Indsæt nedenstående kode i denne komponent.

For nu er dette en meget enkel komponent. Vi redigerer dette senere for at tilføje en registreringsformular og sætte nogle funktioner i den.

Produktion

Når du har oprettet alle mapper og filer ovenfor, skal du køre npm starti dit projekt og åbne//localhost:3000i din browser. Du skal kunne se nedenstående resultat.

Ved at klikke på login her omdirigeres ikke til login-ruten, som vi løser derefter.

Få det til at fungere

Routing

For routing til arbejde skal du først oprette en ny komponent inde i komponentmappen. Navngiv det, loginPage.jsog placer nedenstående kode inde i denne komponent.

Denne komponent er meget enkel. Det gengiver grundlæggende indhold og et link til registrering af komponenten.

Åbn nu routes.jsfilen, som vi allerede har oprettet ovenfor, og foretag følgende ændringer.

Skift indeksruten til, LoginPagefordi vi ønsker, at brugerne lander på login-komponenten, når de besøger hjemmesiden. Før du gør det, skal du importere det fra komponentmappen.

Opdater nu din browser, og du skal kunne se loginPageførst. Når du klikker på "Registrer her" linket registerPageskal gengives.

Nu har vi de grundlæggende ruter, der fungerer.

Login og registrering

Registrering

For at få loginprocessen til at fungere, håndterer jeg først registreringsprocessen, så vi tilføjer nogle brugere i vores database. Så lad os gå videre og åbne components/registerPage.jsog opdatere det med nedenstående indhold.

Der ser ud til at være meget kode i denne fil nu, men det er alt sammen simpelt. Først importerer viconnectat forbinde vores storemedregisterPagekomponent. Så importerer viregisterUserActionsom vi skriver næste.

Inde i renderfunktionen kontrollerer jeg først svaret fra serveren, hvis det findes, og tildeler derefter succes- og beskedegenskaber, der modtages fra serveren. Dette kan være en separat funktion, men for enkelhedens skyld placerede jeg dem i renderfunktionen.

Dernæst er der en registreringsformular. Når brugeren klikker på registerknappen, udløses den onHandleRegistrationfunktion, der får brugerens indtastede data fra formularen, ogdispatch registerUserActionmed deres data som parametre. Vi skal skrive handlinger i næste trin.

For at ovenstående kode skal fungere, har vi brug for mapStateToProps, som vi gør i bunden af ​​komponenten, og derefter forbinde den med registerPagekomponenten i slutningen.

Handlinger

Nu er det tid til at tilføje handlinger. Gå videre og opretsrc/actionsfolder. Opretindex.jsfil og placer nedenstående kode i den.

Denne kode eksporterer nogle konstanter, som vi vil bruge i hele vores projekt.

Gå nu videre og opret authenticationActions.jsfil i den samme mappe, og placer nedenstående kode i den.

Her importerer jeg indeksfilen, der eksporterer konstanter, og derefter export registrationUserActionreturnerer jeg et objekt med handlingstype og brugerdata. Handlingstype i dette tilfælde er REGISTER_USER. Denne handling sendes, når en bruger prøver at registrere sig, og denne handling vil være tilgængelig i hele vores projekt, som vi vil lytte til i vores sagaer.

Sagas

Nu er vi på det tidspunkt, hvor vi kan introducere vores sagaer i vores projekt. Hvis du er ny hos Redux-Saga, foreslår jeg, at du træder på denne blog, inden du fortsætter.

Hvis du allerede kender til sagaer, skal du fortsætte med at oprette en src/sagasfolder. Opretindex.jsfil, og placer nedenstående kode i denne fil.

I ovenstående fil importerer jeg først forkfra effectsogwatchUserAuthenticationfra watchers- som ikke findes endnu, men vi laver den fil næste. Så eksporterer jeg simpelthen en generatorfunktion og gaffel watchUserAuthentication.

Gå nu videre og opret en watcher.jsfil i den samme mappe som ovenfor, og placer nedenstående kode i denne fil.

Igen importerer jeg takeLatesteffekt fra redux-saga, derefter registerSagafra authenticationSaga.js, som vi opretter derefter. Importér derefter actions/index.jssom typer.

Jeg eksporterer en generatorfunktion, der dybest set holder øje med REGISTER_USERhandlingen og ringer til registerSaga.

Lad os nu oprette authenticatioSaga.jssaga i samme mappe som ovenfor, og placere nedenstående kode i denne fil.

I denne saga importerer jeg endnu et par effekter - putog callfra redux-saga. Derefter registerUserServiceimporteres fra service/authenticationService.js. Jeg importerer alle handlinger som typer fra actions/index.js. Så eksporterer jeg generatorfunktionen registerSaga.

Denne funktion er ansvarlig for at ringe registerUserService, hvilket foretager et ajax-opkald til vores server for at registrere ny bruger - som jeg vil skrive efter dette trin. Det modtager et svar fra registerUserServiceog sætter REGISTER_USER_SUCCESShandlingen. Hvis der er en fejl, sætter den REGISTER_USER_ERRORhandlingen.

Importer sagaerne

Nu hvor vi har vores sagaer, er det tid til at importere dem i vores butik. Åbn store/configureStore.jsog opdater indholdet med nedenstående indhold.

Her er jeg importere createSagaMiddleware, rootReducerog rootSaga. Derefter configureStoreopretter jeg en ny funktion inde i funktionen sagaMiddlewareog videregiver den til createStorebrug af applyMiddlewarefunktionen. Endelig kører jeg rootSaga.

Nu er det tid til at oprette src/servicesmappen og oprette en ny første tjeneste. Navngiv detauthenticationService.jsog placer nedenstående kode i denne service.

Denne fil udfører en grundlæggende ajax-anmodning ved hjælp af hent-API med nogle parametre og overskrift. Det er en temmelig selvforklarende tjeneste.

Reducer

Nu hvor vi fremsætter en anmodning til serveren, er det tid til at modtage svaret i vores komponent. For at gøre dette har vi brug for en reducering . Gå videre og opret enreducers/registerReducer.jsfil, og placer nedenstående kode i den.

Det er en simpel reduceringsfunktion, der får tilstand og returnerer ny tilstand. Det kontrollerer for REGISTER_USER_SUCCESSog REGISTER_USER_ERRORhandlinger og returnerer den nye tilstand til komponenten.

Gå nu videre og åbn src/reducers/index.jsfil og opdatere den med følgende indhold.

I dette rootReducervil jeg importere alle reduktionsgear og derefter kombinere dem inden eksport. Det er præcis det, jeg laver med register.

Kører den opdaterede kode

Nu er vi færdige med registreringsprocessen. Det er tid til at opdatere din browser, gå til registerruten og indtaste nogle data. Hvis du indtaster en eksisterende e-mail, skal du se nedenstående resultat.

Hvis du indtaster en ny e-mail, skal du omdirigeres til loginPage, som vi næste gang implementerer.

Log på

Det er på tide for os at logge ind på brugeren, efter at de er registreret. Gå videre og åbncomponents/loginPage.jsfil og opdatere den med følgende indhold.

Denne komponent er stort set den samme som registerPage. Den eneste forskel er, at den sendesloginUserActionsom vi skal skrive næste. En anden forskel er, at hvis svaret fra serveren lykkes, vil jeg modtage en JWT token. Jeg gemmer det token i localStorage. Du kan bruge en anden metode, men til dette eksempel bruger jeg denne tilgang.

Gå videre og åbn actions/authenticationActions.jsog opdater det med følgende indhold.

Her eksporterer jeg den nye loginUserActionfunktion med LOGIN_USERhandlingstype og user payload.

Inden du går videre, skal du åbne actions/index.jsfilen og opdatere dens indhold med følgende.

Gå nu videre og åbn sagas/watchers.jsfil og opdatere dens indhold med følgende.

Her importerer jeg loginSagaog kalder det bare, når den modtagerLOGIN_USERhandling.

Det har vi ikke loginSagaendnu. Af den grund gå videre og åbnesagas/authenticationSaga.jssaga og opdatere dens indhold med følgende.

Her er jeg importerer en ekstra service - loginUserService, som jeg vil gennemføre næste - og så eksportere den nye generator funktion med navnet loginSaga, der gør stort set det samme som registerSaga.

Åbn nu services/authenticationService.jsservice og opdatere dens indhold med følgende.

Her tilføjer jeg loginUserService, som gør stort set det samme som registerUserService, dvs. at sende en ajax-anmodning om at logge på brugeren.

Nu hvor vi med succes har sendt en anmodning til serveren, er det tid til at modtage et svar fra vores server til vores login-komponent. Til det skal du oprette en ny reducer / loginReducer.js reducer og placere nedenstående kode i den.

Det gør stort set det samme som registerReducer- at lytte til LOGIN_USER_SUCCESSog LOGIN_USER_ERRORhandlinger, og returnere den nye stat.

Åbn nu reducers/index.jsfil og opdatere dens indhold med koden nedenfor.

Her importerer loginReducerog kombinerer jeg det med, registerfør jeg returnerer det som rootReducer.

Efter dette skal du opdatere din browser og indtaste en e-mail, der endnu ikke er registreret. Efter at have trykket på login-knappen skal du se nedenstående resultat.

Hvis du indtaster en registreret e-mail, skal anmodningen være vellykket, men du skal ikke se noget endnu, da jeg ikke har implementeret dashboardPagekomponent. Dette er kun tilgængeligt efter vellykket godkendelse. Når det er sagt, lad os implementere det.

Dashboard-side

Opret nu components/dashboardPage.jskomponent og placer nedenstående kode i denne komponent.

Dette er en meget enkel komponent - alt det gør er at returnere Dashboardteksten.

Åbn nu routes/index.jsrute og opdatere dens indhold med følgende.

Her laver jeg nogle nye ting. Først importerer jeg en dashboardPageog føjer den til route. Nårdashboardrute er adgang til requireAuthfunktionen udløses. Denne funktion kontrollerer, om brugeren er det loggedIneller ej. For at kontrollere det leder jeg eftertokeni localStorage, som jeg lagrede i loginPagekomponenten ved vellykket login. Hvis den findes, dashboardPagegengives den til brugeren.

Nu når du opdaterer siden i din browser, skal du indtaste en registreret e-mail og trykke på enter, skal du se nedenstående resultater.

Så der er det, dette er et komplet login-system ved hjælp af React, Redux og Redux-Saga. Hvis du gerne vil se hele projektet, skal du klone dette lager.

Jeg håber du nød dette indlæg.