كيفية إعداد مصادقة المستخدم باستخدام React و Redux و Redux Saga

تحديث (12.02.2019): لقد قمت مؤخرًا بتحديث هذا المشروع بأحدث أجهزة توجيه التفاعل ، أي الإصدار 4.3.1 وهو رد فعل جهاز التوجيه دوم. يرجى التوجه إلى المستودع الخاص به لعرض التغييرات.

في مدونتي السابقة ، كتبت كيفية كتابة بنية قابلة للتطوير في Node.js. منذ أن استخدمت ساعي البريد لاختبار عمل تلك المنصة ، اعتقدت أن هذه ستكون فكرة جيدة لتنفيذ جانب العميل. لكتابة جانب العميل ، قررت استخدام المكدس الفني أدناه:

  • تتفاعل
  • إعادة
  • ردوكس ساغا
  • رد فعل راوتر

يفترض هذا المنشور أنك تعرف بالفعل التفاعل والمفاهيم الأساسية لـ 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 ، فأقترح عليك أن تدوس هذه المدونة قبل المتابعة.

إذا كنت تعرف بالفعل الملاحم ، فابدأ في إنشاء ملف src/sagasمجلد. قم بإنشاء ملفindex.jsملف ، ووضع الكود أدناه في هذا الملف.

في الملف أعلاه ، أقوم أولاً بالاستيراد forkمن effectsوwatchUserAuthenticationمن watchers- وهو غير موجود بعد ولكننا سنجعل هذا الملف بعد ذلك. ثم أقوم ببساطة بتصدير وظيفة المولد وشوكة ملف watchUserAuthentication.

الآن انطلق وأنشئ watcher.jsملفًا في نفس المجلد على النحو الوارد أعلاه ، ثم ضع الكود أدناه في هذا الملف.

مرة أخرى ، أنا أستورد takeLatestتأثير من redux-sagaثم registerSagaمن authenticationSaga.jsالذي سننشئه بعد ذلك. بعد ذلك ، قم بالاستيراد actions/index.jsكأنواع.

أقوم بتصدير وظيفة المولد التي تراقب بشكل أساسي REGISTER_USERالإجراء وتتصل به registerSaga.

لنقم الآن بإنشاء authenticatioSaga.jssaga في نفس المجلد كما هو مذكور أعلاه ، ووضع الكود أدناه في هذا الملف.

في هذه القصة وأنا استيراد بضع المزيد من الآثار - 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 الأساسي باستخدام fetch API مع بعض المعلمات والعنوان. إنها خدمة جميلة لا تحتاج إلى شرح.

المخفض

الآن بعد أن قدمنا ​​طلبًا إلى الخادم ، حان الوقت لتلقي هذه الاستجابة في المكون الخاص بنا. للقيام بذلك نحتاج إلى مخفض . انطلق وأنشئ ملفreducers/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 لتسجيل دخول المستخدم.

الآن وقد أرسلنا طلبًا بنجاح إلى الخادم ، فقد حان الوقت لتلقي استجابة من خادمنا إلى مكون تسجيل الدخول الخاص بنا. لذلك ، قم بإنشاء مخفضات / 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. إذا كنت ترغب في رؤية المشروع بأكمله ، فاستنسخ هذا المستودع.

اتمنى أنك استمتعت بهذا المنشور.