Cara mengatur otentikasi pengguna menggunakan React, Redux, dan Redux Saga

UPDATE (12.02.2019): Saya baru saja memperbarui proyek ini dengan router react terbaru yaitu versi 4.3.1 yang merupakan react-router-dom. Silakan menuju ke repositori untuk melihat perubahannya.

Di blog saya sebelumnya, saya menulis cara menulis arsitektur yang dapat diskalakan di Node.js. Karena saya menggunakan tukang pos untuk menguji kerja platform itu, saya pikir ini akan menjadi ide yang baik untuk menerapkan sisi kliennya. Untuk menulis sisi kliennya, saya memutuskan untuk menggunakan tumpukan teknologi di bawah ini:

  • Reaksi
  • Redux
  • Redux-Saga
  • Bereaksi Router

Posting ini mengasumsikan bahwa Anda sudah mengetahui reaksi dan konsep dasar Redux dan Redux-Saga.

Mulai

Gandakan repositori blog saya sebelumnya. CDke dalam folder root dan jalankan npm install. Ini akan menginstal semua dependensi.

Kedua, instal mongodbdi mesin Anda. Setelah terinstal, jalankan server mongo menggunakanmongodperintah di terminal Anda, jika tidak dimulai sebagai layanan di mesin Anda.

Selanjutnya, pastikan paket nodemon diinstal pada mesin Anda secara global . Buka folder sisi server dan jalankannodemon index.jsuntuk menjalankan server backend.

Sekarang backend kita aktif dan berjalan, saatnya untuk masuk ke implementasi sisi kliennya.

Jika Anda belum menginstal create-react-appkemudian lanjutkan menginstalnya menggunakan perintah berikut.

npm install create-react-app -g

Perintah ini akan menginstal create-react-appsecara global .

Buat proyek

Sekarang saatnya membuat proyek. Menggunakan:

create-react-app react-login

Ini akan membuat proyek baru dengan nama tersebut react-login. Silakan cdmasuk ke folder itu. Bukalahpackage.jsonfile di editor favorit Anda dan tambahkan dependensi berikut:

Kami tidak membutuhkan properti tambahan apa pun dalam package.jsonfile ini . Kita dapat menghapusnya begitu saja, tetapi saya akan membiarkannya apa adanya dan maju sehingga kita mendapatkan bagian yang menarik di blog ini.

Sekarang jalankan saja:

npm install

yang akan menginstal semua dependensi yang kami sebutkan di atas.

File indeks

Untuk memulai, buka index.jsfile dan tempatkan kode di bawah ini ke dalam file ini.

Dalam kode ini kami mengimpor reactdan react-dom. Kemudian kami mengimpor Routerdan browserHistorydari react-router. Ini diperlukan untuk tujuan perutean, yang akan saya gunakan nanti diroutes/index.jsmengajukan. Selanjutnya, kami mengimpor Provider, ini digunakan untuk menyediakan penyimpanan ke komponen anak.

configureStoredan routessesuatu yang akan kita impor selanjutnya dan yang akan saya terapkan sebentar lagi. Impor saja apa adanya dan gunakan dalam file ini seperti yang ditunjukkan di atas.

Sekarang file indeks kita sudah siap.

Konfigurasi penyimpanan

Buat folder baru bernama storedi dalam srcmap. Di dalam folder baru itu, buat file bernama configureStore.js,dan tempel kode berikut ke dalam file itu.

Pertama kita mengimpor createStore, yang akan digunakan untuk createStore, dan applyMiddleware, yang akan digunakan apply middlewares ke toko kita - saga dalam hal ini, tapi kita akan membahasnya nanti di blog ini - dari redux.

Kami kemudian mengimpor rootReducer- kami akan membuatnya nanti. Untuk saat ini, cukup impor dan gunakan apa adanya. Ini diikuti oleh fungsi configureStore, yang mengembalikan objek dengan memanggil createStorefungsi tersebut dan meneruskan rootReducersebagai parameter.

Akhirnya, export configureStoremembuat configureStoretersedia di index.jsberkas, dibangun sebelumnya.

Sekarang keluar dari cara kita, lanjutkan dan buat file src/reducersfolder, buat file index.js dan tempel kode di bawah ini di file ini.

File ini bertanggung jawab untuk mengimpor sisa reduksi di dalam folder reduksi, menggabungkannya, dan mengekspornya sehingga tersedia untuk digunakan configureStore.js. Kami akan membuat perubahan pada file ini ketika kami menambahkan reduksi baru nanti di blog ini.

File perutean

Waktu untuk file rute. Silakan dan buat filesrc/routesfolder dan di dalam folder ini buat file index.jsmengajukan. Sekarang buka dan tempel kode di bawah ini.

Tujuan utama file ini adalah untuk menangani perutean dalam proyek kami. Impor file React, Routedan IndexRoute. Setelah itu, kami membutuhkan container, dalam hal ini saya sedang mengimpor container/App, yang akan segera kami tulis. Berikutnya adalah RegisterPage, yang merupakan komponen, dan kami akan menulisnya juga.

Di induk Route, ketika jalur beranda cocok maka kami hanya merender Appwadah kami . Pada IndexRoutepengguna akan melihat RegisterPageyang akan dirender di dalam Appwadah.

Wadah

Sekarang waktunya untuk wadah. Lanjutkan dan buat folder baru bernama container. Di dalam folder ini buat file baru bernama App.jsdan tempatkan kode di bawah ini ke dalam file ini.

Ini sangat mudah. Tujuan utama dari file ini adalah untuk merender komponen lainnya.{this.props.children}melayani tujuan ini.

Registrasi

Sekarang waktunya untuk registerPage. Buat folder barusrc/componentsdan buat sebuah komponen di dalam folder komponen bernamaregisterPage.js. Tempel kode di bawah ini ke dalam komponen ini.

Untuk saat ini, ini adalah komponen yang sangat sederhana. Kami akan mengedit ini nanti untuk menambahkan formulir pendaftaran dan memasukkan beberapa fungsionalitas ke dalamnya.

Keluaran

Setelah membuat semua folder dan file di atas, jalankan npm startproyek Anda, dan buka//localhost:3000di browser Anda. Anda harus bisa melihat hasil di bawah ini.

Mengklik login di sini tidak akan mengarahkan ke rute login yang akan kita perbaiki selanjutnya.

Membuatnya berhasil

Rute

Agar perutean berfungsi, pertama-tama buat komponen baru di dalam folder komponen. Beri nama loginPage.jsdan tempatkan kode di bawah ini di dalam komponen ini.

Komponen ini sangat sederhana. Ini membuat konten dasar dan tautan untuk mendaftarkan komponen.

Sekarang buka routes.jsfile, yang telah kita buat di atas, dan lakukan perubahan berikut.

Ubah rute indeks menjadi LoginPagekarena kami ingin pengguna membuka komponen login saat mereka mengunjungi halaman beranda. Sebelum melakukan itu, impor dari folder komponen.

Sekarang segarkan browser Anda dan Anda seharusnya sudah bisa melihatnya loginPageterlebih dahulu. Saat Anda mengklik link "Daftar di sini", registerPageseharusnya sudah ditampilkan.

Sekarang kami memiliki rute dasar yang berfungsi.

Login dan registrasi

Registrasi

Untuk membuat proses login bekerja, saya akan menangani proses registrasi terlebih dahulu sehingga kami menambahkan beberapa pengguna di database kami. Jadi mari kita lanjutkan dan buka components/registerPage.jsdan perbarui dengan konten di bawah ini.

Sepertinya ada banyak kode di file ini sekarang, tapi semuanya sederhana. Pertama kami mengimporconnectuntuk menghubungkan kami storedenganregisterPagekomponen. Lalu kami imporregisterUserActionyang akan kami tulis selanjutnya.

Di dalam renderfungsi, pertama-tama saya memeriksa respons dari server jika ada, kemudian menetapkan properti pesan dan keberhasilan yang diterima dari server. Ini bisa menjadi fungsi yang terpisah tetapi, demi kesederhanaan, saya menempatkannya di dalam renderfungsi.

Selanjutnya ada formulir pendaftaran. Ketika pengguna mengklik tombol register, itu memicu onHandleRegistrationfungsi yang mendapatkan data yang dimasukkan pengguna dari formulir, dandispatch registerUserActiondengan datanya sebagai parameter. Kami akan menulis tindakan di langkah berikutnya.

Agar kode di atas berfungsi, kita perlu mapStateToProps, seperti yang kita lakukan di bagian bawah komponen, lalu menghubungkannya dengan registerPagekomponen di bagian akhir.

Tindakan

Sekarang saatnya menambahkan tindakan. Silakan dan buat filesrc/actionsmap. Buatindex.jsfile dan tempatkan kode di bawah ini di dalamnya.

Kode ini mengekspor beberapa konstanta yang akan kita gunakan di seluruh proyek kita.

Sekarang lanjutkan dan buat file authenticationActions.jsfile di dalam folder yang sama, dan tempatkan kode di bawah ini di dalamnya.

Di sini saya mengimpor file indeks, yang mengekspor konstanta, lalu saya export registrationUserActiondan mengembalikan objek dengan tipe tindakan dan data pengguna. Jenis tindakan dalam kasus ini adalah REGISTER_USER. Tindakan ini akan dikirim saat pengguna mencoba mendaftar, dan tindakan ini akan tersedia di seluruh proyek kami yang akan kami dengarkan di saga kami.

Sagas

Sekarang kami berada pada tahap di mana kami dapat memperkenalkan saga kami dalam proyek kami. Jika Anda baru mengenal Redux-Saga, saya sarankan Anda menginjak blog ini sebelum melanjutkan.

Jika Anda sudah mengetahui tentang saga, lanjutkan dan buat src/sagasmap. Buatindex.jsfile, dan tempatkan kode di bawah ini ke dalam file ini.

Pada file di atas, pertama saya mengimpor forkdari effectsdanwatchUserAuthenticationdari watchers- yang belum ada tapi kami akan membuat file itu selanjutnya. Kemudian saya cukup mengekspor fungsi generator dan garpu watchUserAuthentication.

Sekarang lanjutkan dan buat watcher.jsfile di folder yang sama seperti di atas, dan tempatkan kode di bawah ini ke dalam file ini.

Sekali lagi, saya mengimpor takeLatestefek dari redux-saga, lalu registerSagadari authenticationSaga.js, yang akan kita buat selanjutnya. Selanjutnya, impor actions/index.jssebagai tipe.

Saya mengekspor fungsi generator yang pada dasarnya mengawasi REGISTER_USERtindakan dan membuat panggilan ke registerSaga.

Sekarang mari buat authenticatioSaga.jssaga di folder yang sama seperti di atas, dan tempatkan kode di bawah ini ke dalam file ini.

Dalam saga ini saya mengimpor beberapa efek lagi - putdan calldari redux-saga. Kemudian registerUserServicediimpor dari service/authenticationService.js. Saya mengimpor semua tindakan sebagai jenis dari actions/index.js. Lalu saya mengekspor fungsi generator registerSaga.

Fungsi ini bertanggung jawab untuk memanggil registerUserService, yang membuat panggilan ajax ke server kami untuk mendaftarkan pengguna baru - yang akan saya tulis setelah langkah ini. Ia menerima tanggapan dari registerUserServicedan menempatkan REGISTER_USER_SUCCESStindakan. Jika ada kesalahan maka itu menempatkan REGISTER_USER_ERRORtindakan.

Impor saga

Sekarang setelah kita memiliki saga, sekarang saatnya untuk mengimpornya di toko kita. Buka store/configureStore.jsdan perbarui isinya dengan konten di bawah ini.

Di sini saya mengimpor createSagaMiddleware, rootReducer, dan rootSaga. Kemudian, di dalam configureStorefungsi, saya membuat yang baru sagaMiddlewaredan meneruskannya createStoremenggunakan applyMiddlewarefungsi tersebut. Akhirnya, saya menjalankan rootSaga.

Sekarang saatnya membuat src/servicesfolder dan membuat layanan pertama yang baru. Beri namaauthenticationService.jsdan tempatkan kode di bawah ini ke dalam layanan ini.

File ini melakukan permintaan ajax dasar menggunakan fetch API dengan beberapa parameter dan header. Ini adalah layanan yang cukup jelas.

Peredam

Sekarang kita membuat permintaan ke server, sekarang saatnya menerima respon itu di komponen kita. Untuk melakukan ini kita membutuhkan peredam . Silakan dan buat filereducers/registerReducer.jsfile dan tempatkan kode di bawah ini ke dalamnya.

Ini adalah fungsi peredam sederhana yang mendapat status dan mengembalikan status baru. Ia memeriksa REGISTER_USER_SUCCESSdan REGISTER_USER_ERRORtindakan, dan mengembalikan status baru ke komponen.

Sekarang lanjutkan dan buka src/reducers/index.jsfile dan perbarui dengan konten berikut.

Dalam hal ini rootReducersaya akan mengimpor semua reduksi dan kemudian menggabungkannya sebelum mengekspor. Itulah yang saya lakukan dengan register.

Menjalankan kode yang diperbarui

Sekarang kita sudah selesai dengan proses registrasi. Saatnya menyegarkan browser Anda, pergi ke rute register, dan masukkan beberapa data. Jika Anda memasukkan email yang sudah ada maka Anda akan melihat hasil di bawah ini.

Jika Anda memasukkan email baru maka Anda akan dialihkan ke loginPage, yang akan kita terapkan selanjutnya.

Gabung

Sudah waktunya bagi kita untuk login pengguna setelah mereka terdaftar. Silakan bukacomponents/loginPage.jsfile dan perbarui dengan konten berikut.

Komponen ini hampir sama dengan registerPage. Satu-satunya perbedaan adalah bahwa itu mengirimloginUserActionyang akan kita tulis selanjutnya. Perbedaan lainnya adalah, jika respon dari server berhasil, saya akan menerima JWT token. Saya menyimpan token itu di localStorage. Anda dapat menggunakan metode yang berbeda tetapi untuk contoh ini saya menggunakan pendekatan ini.

Silakan buka actions/authenticationActions.jsdan perbarui dengan konten berikut.

Di sini saya mengekspor loginUserActionfungsi baru dengan LOGIN_USERjenis tindakan dan user payload.

Sebelum melanjutkan, lanjutkan dan buka actions/index.jsfile dan perbarui isinya dengan yang berikut ini.

Sekarang lanjutkan dan buka sagas/watchers.jsfile dan perbarui isinya dengan yang berikut ini.

Di sini saya hanya mengimpor loginSagadan memanggilnya ketika menerimaLOGIN_USERtindakan.

Kami belum punya loginSaga. Untuk alasan itu silakan bukasagas/authenticationSaga.jssaga dan perbarui isinya dengan yang berikut ini.

Di sini saya mengimpor layanan tambahan - loginUserService, yang akan saya terapkan selanjutnya - dan kemudian mengekspor fungsi generator baru bernama loginSaga, yang melakukan hal yang hampir sama seperti registerSaga.

Sekarang buka services/authenticationService.jslayanan dan perbarui isinya dengan yang berikut ini.

Di sini saya menambahkan loginUserService yang melakukan hampir sama dengan registerUserService yaitu mengirim permintaan ajax untuk login pengguna.

Sekarang setelah kita berhasil mengirim permintaan ke server, sekarang saatnya menerima respon dari server kita ke komponen login kita. Untuk itu buat reducer baru reducers / loginReducer.js dan tempatkan kode di bawah ini ke dalamnya.

Ia melakukan hal yang hampir sama dengan registerReducer- mendengarkan LOGIN_USER_SUCCESSdan LOGIN_USER_ERRORbertindak, dan mengembalikan keadaan baru.

Sekarang buka reducers/index.jsfile dan perbarui isinya dengan kode di bawah ini.

Di sini saya mengimpor loginReducerdan menggabungkannya dengan registersebelum mengembalikannya sebagai rootReducer.

Setelah ini, segarkan browser Anda dan masukkan email yang belum terdaftar. Setelah menekan tombol login, Anda akan melihat hasil di bawah ini.

Jika Anda memasukkan email terdaftar maka permintaan tersebut seharusnya berhasil, tetapi Anda belum melihat apa pun, karena saya belum menerapkan dashboardPagekomponen. Ini hanya akan diakses setelah otentikasi berhasil. Karena itu, mari kita terapkan.

Halaman dasbor

Sekarang buat components/dashboardPage.jskomponen dan tempatkan kode di bawah ini ke dalam komponen ini.

Ini adalah komponen yang sangat sederhana - yang dilakukannya hanyalah mengembalikan Dashboardteks.

Sekarang buka routes/index.jsmerutekan dan memperbarui isinya dengan yang berikut ini.

Di sini saya melakukan beberapa hal baru. Pertama saya mengimpor dashboardPagedan menambahkannya ke route. Ketikadashboardrute diakses requireAuthfungsi akan dipicu. Fungsi ini memeriksa apakah pengguna loggedInatau tidak. Untuk memeriksanya, saya sedang mencaritokendi localStorage, yang saya simpan di loginPagekomponen saat login berhasil. Jika memang ada, maka dashboardPageakan diberikan kepada pengguna.

Sekarang ketika Anda menyegarkan halaman di browser Anda, masukkan email terdaftar, dan tekan enter, Anda akan melihat hasil di bawah ini.

Jadi begitulah, ini adalah sistem login lengkap menggunakan React, Redux dan Redux-Saga. Jika Anda ingin melihat keseluruhan proyek, klon gudang ini.

Saya harap anda menikmati postingan ini.