Как да настроите удостоверяване на потребителя чрез React, Redux и Redux Saga

АКТУАЛИЗАЦИЯ (12.02.2019): Наскоро актуализирах този проект с най-новите рутери за реагиране, т.е. версия 4.3.1, която е response-router-dom. Моля, насочете се към хранилището му, за да видите промените.

В предишния си блог написах как да напиша мащабируема архитектура в Node.js. Тъй като използвах пощальон, за да тествам работата на тази платформа, мислех, че би било добра идея да има внедряване от страна на клиента. За да напиша клиентската си страна, реших да използвам технологичния стек по-долу:

  • Реагирайте
  • Redux
  • Редукс-Сага
  • React Router

Тази публикация предполага, че вече знаете реакцията и основните концепции на Redux и Redux-Saga.

Приготвяме се да започнем

Клонирайте предишното ми хранилище на блог. CDв основната си папка и стартирайте npm install. Това ще инсталира всички зависимости.

На второ място, инсталирайте mongodbвъв вашата машина. Веднъж инсталиран, стартирайте mongo сървър, използвайкиmongodкоманда във вашия терминал, ако не е стартиран като услуга във вашата машина.

След това се уверете, че пакетът nodemon е инсталиран на вашата машина глобално . Отидете до папката от страна на сървъра и стартирайтеnodemon index.jsза да стартирате бекенд сървъра.

Сега, когато нашият бекенд е готов и работи, е време да влезем в неговата клиентска реализация.

Ако все още не сте инсталирали create-react-appслед това продължете да го инсталирате, като използвате следната команда.

npm install create-react-app -g

Тази команда ще се инсталира create-react-appв световен мащаб .

Създайте проекта

Сега е време да създадете проект. Употреба:

create-react-app react-login

Това ще създаде нов проект с името react-login. Продължете и влезте cdв тази папка. Отвори сиpackage.jsonфайл във вашия любим редактор и добавете следните зависимости:

Не се нуждаем от допълнителни свойства в този package.jsonфайл. Можем просто да ги премахнем, но ще го оставя както е и ще продължа напред, така че да стигнем до интересна част в този блог.

Сега просто изпълнете:

npm install

което ще инсталира всички зависимости, които споменахме по-горе.

Индекс файл

За начало отворете index.jsфайл и поставете кода по-долу в този файл.

В този код ние импортираме reactи react-dom. След това внасяме Routerи browserHistoryот react-router. Те са необходими за целите на маршрутизирането, които ще използвам по-късно вroutes/index.jsфайл. След това импортираме Provider, това се използва за осигуряване на съхранение на дъщерни компоненти.

configureStoreи routesса нещо, което ще импортираме следващо и което ще приложа след секунда. Просто ги импортирайте както са и ги използвайте в този файл, както е показано по-горе.

Сега нашият индексен файл е настроен.

Конфигурация на магазина

Създайте нова папка, наречена storeвътре в srcпапка. Вътре в тази нова папка създайте файл, наречен configureStore.js,и поставете следния код в този файл.

Първо импортираме createStore, което ще бъде свикнало createStoreи applyMiddleware, което ще се използва, прилагаме посреднически продукти към нашия магазин - саги в този случай, но ще разгледаме това по-късно в този блог - от redux.

След това импортираме rootReducer- ще създадем това по-късно. Засега просто го импортирайте и го използвайте както е. Това е последвано от функцията configureStore, която връща обект чрез извикване на createStoreфункцията и предаване rootReducerкато параметър.

И накрая, export configureStoreправи configureStoreдостъпна във index.jsфайла, създаден по-рано.

Сега това ни е извън пътя, продължете напред и създайте src/reducersпапка, създайте файл index.js и поставете кода по-долу в този файл.

Този файл е отговорен за импортирането на останалите редуктори в папката на редукторите, комбинирането им и експортирането им, така че да са достъпни за използване в configureStore.js. Ще направим промени в този файл, когато добавим нови редуктори по-късно в този блог.

Маршрутизиращ файл

Време за файла с маршрутите. Продължете и създайтеsrc/routesи вътре в тази папка създайте index.jsфайл. Сега го отворете и поставете кода по-долу.

Основната цел на този файл е да се справи с маршрутизацията в нашия проект. Вноса на файловете React, Routeкакто и IndexRoute. След това се нуждаем от контейнер, в този случай аз импортирам container/App, който скоро ще напишем. Следващото е RegisterPage, което е компонент, и ние ще напишем и това.

В родителя Route, когато началният път съвпада, ние просто изобразяваме Appконтейнера си. На IndexRouteпотребителите ще видите RegisterPage, които ще бъдат предоставени в рамките на Appконтейнера.

Контейнер

Сега е време за контейнера. Продължете и направете нова папка, наречена container. Вътре в тази папка създайте нов файл, наречен App.jsи поставете кода по-долу в този файл.

Това е доста лесно. Основната цел на този файл е да изобрази останалите компоненти.{this.props.children}служи за тази цел.

Регистрация

Сега е време за registerPage. Създайте нова папкаsrc/componentsи създайте компонент в папката с компоненти, нареченregisterPage.js. Поставете кода по-долу в този компонент.

Засега това е много прост компонент. Ще редактираме това по-късно, за да добавим регистрационен формуляр и да добавим някои функции в него.

Изход

След като създадете всички папки и файлове по-горе, стартирайте npm startпроекта си и отворете//localhost:3000във вашия браузър. Трябва да можете да видите резултата по-долу.

Кликването върху вход тук няма да пренасочи към маршрута за влизане, който ще коригираме по-нататък.

Правейки го да работи

Маршрутизиране

За да работи маршрутизацията, първо направете нов компонент в папката с компоненти. Дайте му име loginPage.jsи поставете кода по-долу в този компонент.

Този компонент е много прост. Той предоставя основно съдържание и връзка за регистриране на компонента.

Сега отворете routes.jsфайла, който вече създадохме по-горе, и направете следните промени.

Променете маршрута на индекса на, LoginPageзащото искаме потребителите да кацнат на компонента за вход, когато посещават началната страница. Преди да го направите, импортирайте го от папката с компоненти.

Сега опреснете браузъра си и трябва да можете да видите loginPageпърво. Когато кликнете върху връзката „Регистрирайте се тук“, registerPageтрябва да се изобрази.

Сега работим основните маршрути.

Вход и регистрация

Регистрация

За да задействам процеса на влизане, първо ще се справя с процеса на регистрация, така че да добавим някои потребители в нашата база данни. Така че нека да отворим components/registerPage.jsи да го актуализираме със съдържанието по-долу.

Изглежда, че в този файл сега има много код, но всичко е просто. Първо внасямеconnectда свържете нашите storeсregisterPageкомпонент. След това внасямеregisterUserActionкоето ще напишем по-нататък.

Вътре във renderфункцията първо проверявам отговора от сървъра, ако той съществува, след това присвоявам успех и свойства на съобщенията, получени от сървъра. Това може да е отделна функция, но за по-голяма простота ги поставих във renderфункцията.

След това има формуляр за регистрация. Когато потребителят щракне върху бутона за регистрация, той задейства onHandleRegistrationфункцията, която получава въведените от потребителя данни от формуляра, иdispatch registerUserActionс техните данни като параметри. Ще напишем действия в следващата стъпка.

За да работи горният код, трябва mapStateToProps, както правим в долната част на компонента, и след това да го свържем с registerPageкомпонента в края.

Действия

Сега е време да добавите действия. Продължете и създайтеsrc/actionsпапка. Създайтеindex.jsфайл и поставете кода по-долу в него.

Този код експортира някои константи, които ще използваме по време на нашия проект.

Сега продължете и създайте authenticationActions.jsфайл в същата папка и поставете кода по-долу в него.

Тук импортирам индексния файл, който експортира константи и след това export registrationUserActionвръщам обект с тип действие и потребителски данни. Типът действие в този случай е REGISTER_USER. Това действие ще бъде изпратено, когато потребителят се опитва да се регистрира и това действие ще бъде достъпно в целия ни проект, който ще слушаме в нашите саги.

Саги

Сега сме на етапа, когато можем да представим нашите саги в нашия проект. Ако не сте запознати с Redux-Saga, предлагам ви да преминете този блог, преди да продължите.

Ако вече знаете за саги, продължете и създайте a src/sagasпапка. Създайтеindex.jsфайл и поставете кода по-долу в този файл.

В горния файл първо импортирам forkот effectsиwatchUserAuthenticationот watchers- което все още не съществува, но ние ще направим този файл след това. След това просто експортирам функция генератор и разклонявам watchUserAuthentication.

Сега продължете и създайте watcher.jsфайл в същата папка, както по-горе, и поставете долния код в този файл.

Отново внасям takeLatestефект от redux-saga, после registerSagaот authenticationSaga.js, който ще създадем следващ. След това импортирайте actions/index.jsкато типове.

Изнасям функция генератор, която основно следи за REGISTER_USERдействието и се обажда registerSaga.

Сега нека създадем authenticatioSaga.jsсага в същата папка, както по-горе, и поставете кода по-долу в този файл.

В тази сага внасям още няколко ефекта - putи callот redux-saga. След това registerUserServiceсе импортира от service/authenticationService.js. Импортирам всички действия като типове от actions/index.js. Тогава експортирам функцията генератор registerSaga.

Тази функция отговаря за извикването registerUserService, което прави извикване ajax към нашия сървър, за да регистрира нов потребител - което ще напиша след тази стъпка. Той получава отговор от registerUserServiceи поставя REGISTER_USER_SUCCESSдействието. Ако има грешка, тогава тя поставя REGISTER_USER_ERRORдействието.

Импортирайте сагите

Сега, когато имаме нашите саги, е време да ги импортираме в нашия магазин. Отворете store/configureStore.jsи актуализирайте съдържанието му със съдържанието по-долу.

Тук съм вносител createSagaMiddleware, rootReducerи rootSaga. След това във configureStoreфункцията създавам нова sagaMiddlewareи я предавам createStoreна applyMiddlewareфункцията. И накрая, аз стартирам rootSaga.

Сега е време да създадете src/servicesпапката и да създадете нова първа услуга. Назовете гоauthenticationService.jsи поставете кода по-долу в тази услуга.

Този файл прави основна заявка за Ajax, използвайки API за извличане с някои параметри и заглавка. Това е доста обяснителна услуга.

Редуктор

Сега, когато отправяме заявка към сървъра, е време да получим този отговор в нашия компонент. За целта се нуждаем от редуктор . Продължете и създайте areducers/registerReducer.jsфайл и поставете кода по-долу в него.

Това е проста функция на редуктор, която получава състояние и връща ново състояние. Той проверява за REGISTER_USER_SUCCESSи REGISTER_USER_ERRORдействия и връща новото състояние на компонента.

Сега продължете и отворете src/reducers/index.jsфайл и го актуализирайте със следното съдържание.

В това rootReducerще импортирам всички редуктори и след това ще ги комбинирам преди експортиране. Точно с това правя register.

Изпълнение на актуализирания код

Сега приключихме с процеса на регистрация. Време е да опресните браузъра си, да отидете на маршрута за регистрация и да въведете някои данни. Ако въведете съществуващ имейл, трябва да видите резултата по-долу.

Ако въведете нов имейл, трябва да бъдете пренасочени към loginPage, което ще приложим по-нататък.

Влизам

Време е да влезем в профила на потребителя, след като той бъде регистриран. Давай и отвориcomponents/loginPage.jsфайл и го актуализирайте със следното съдържание.

Този компонент е почти същият като registerPage. Единствената разлика е, че се изпращаloginUserActionкоето ще напишем по-нататък. Друга разлика е, че ако отговорът от сървъра е успешен, ще получа JWT token. Съхранявам този знак в localStorage. Можете да използвате различен метод, но за този пример използвам този подход.

Давай и отвори actions/authenticationActions.jsи го актуализирайте със следното съдържание.

Тук експортирам новата loginUserActionфункция с LOGIN_USERтип на действие и user payload.

Преди да продължите напред, отворете actions/index.jsфайла и актуализирайте съдържанието му със следното.

Сега продължете и отворете sagas/watchers.jsфайл и актуализирайте съдържанието му със следното.

Тук просто импортирам loginSagaи го извиквам, когато получиLOGIN_USERдействие.

Все loginSagaоще нямаме . По тази причина продължете и отворетеsagas/authenticationSaga.jsсага и актуализирайте съдържанието й със следното.

Тук внасям допълнителна услуга - loginUserService, която ще внедрявам следващата - и след това експортирам новата функция с име на име loginSaga, която прави почти същото като registerSaga.

Сега отворете services/authenticationService.jsуслуга и актуализирайте съдържанието й със следното.

Тук добавям loginUserService, което прави почти същото като registerUserService, т.е. изпращам заявка ajax за влизане на потребителя.

След като успешно изпратихме заявка до сървъра, е време да получим отговор от нашия сървър до нашия компонент за вход. За това създайте нов редуктор reducer / loginReducer.js и поставете кода по-долу в него.

Прави почти същото нещо като registerReducer- слушане LOGIN_USER_SUCCESSи LOGIN_USER_ERRORдействия и връщане на новото състояние.

Сега отворете reducers/index.jsфайл и актуализирайте съдържанието му с кода по-долу.

Тук го внасям loginReducerи комбинирам с registerпреди да го върна като rootReducer.

След това опреснете браузъра си и въведете имейл, който все още не е регистриран. След натискане на бутона за вход трябва да видите резултата по-долу.

Ако въведете регистриран имейл, заявката трябва да е успешна, но все още не трябва да виждате нищо, тъй като не съм приложил dashboardPageкомпонент. Това ще бъде достъпно само след успешно удостоверяване. Като казахме това, нека го приложим.

Страница на таблото за управление

Сега създайте components/dashboardPage.jsкомпонент и поставете кода по-долу в този компонент.

Това е много прост компонент - всичко, което прави, е да върне Dashboardтекста.

Сега отворете routes/index.jsмаршрут и актуализирайте съдържанието му със следното.

Тук правя някои нови неща. Първо импортирам a dashboardPageи го добавям към route. Когатоdashboardмаршрут е достъпен, requireAuthфункцията ще се задейства. Тази функция проверява дали потребителят е loggedInили не. За да проверя това, търсяtokenв localStorage, който запазих в loginPageкомпонента при успешно влизане. Ако съществува, тогава dashboardPageсе визуализира на потребителя.

Сега, когато опресните страницата в браузъра си, въведете регистриран имейл и натиснете enter, трябва да видите резултатите по-долу.

Ето го, това е цялостна система за вход, използваща React, Redux и Redux-Saga. Ако искате да видите целия проект, клонирайте това хранилище.

Надявам се тази публикация да ви е харесала.