Menangani Pemasangan dan Pelepasan Rute Navigasi Di React Native

Diterbitkan: 2022-03-10
Ringkasan cepat Seringkali Anda memerlukan dua set tumpukan navigasi yang berbeda untuk otentikasi pengguna sebelum dan sesudah. Biasanya, untuk melihat lebih banyak konten, Anda harus diautentikasi dengan cara tertentu. Mari kita lihat cara memasang dan melepas tumpukan navigasi berdasarkan kondisi yang terpenuhi di React Native.

Pada artikel ini, kita akan berjalan melalui pemasangan dan pelepasan rute navigasi di React Native. Perilaku yang diharapkan dari aplikasi Anda adalah bahwa setelah kondisi autentikasi terpenuhi, kumpulan rute navigasi baru hanya tersedia untuk pengguna yang masuk, sementara layar lain yang ditampilkan sebelum autentikasi dihapus dan tidak dapat dikembalikan kecuali jika pengguna keluar dari aplikasi.

Untuk keamanan di aplikasi Anda, rute yang dilindungi memberi Anda cara untuk hanya menampilkan informasi/konten tertentu di aplikasi Anda kepada pengguna tertentu, sambil membatasi akses dari orang yang tidak berwenang.

Kami akan bekerja sama dengan Expo untuk proyek ini karena itu akan membantu kami fokus pada masalah yang dihadapi daripada mengkhawatirkan banyak penyiapan. Langkah yang sama persis dalam artikel ini dapat diikuti untuk aplikasi React Native yang kosong.

Anda memerlukan beberapa keakraban dengan JavaScript dan React Native untuk mengikuti tutorial ini. Berikut adalah beberapa hal penting yang harus Anda ketahui:

  • Komponen kustom di React Native (cara membuat komponen, menerima, meneruskan, dan menggunakan alat peraga dalam komponen). Baca lebih banyak.
  • Navigasi Bereaksi. Baca lebih banyak.
  • Stack Navigator di React Native. Baca lebih banyak.
  • Pengetahuan Dasar tentang komponen React Native Core ( <View/> , <Text/> , dll.). Baca lebih banyak.
  • Bereaksi AsyncStorage Asli. Baca lebih banyak.
  • API Konteks. Baca lebih banyak.

Pengaturan Proyek Dan Otentikasi Dasar

Jika Anda baru menggunakan expo dan tidak tahu cara menginstal expo, kunjungi dokumentasi resmi. Setelah instalasi selesai, lanjutkan untuk menginisialisasi proyek React Native baru dengan expo dari command prompt kami:

 expo init navigation-project

Anda akan disajikan dengan beberapa opsi untuk memilih bagaimana Anda ingin pengaturan dasar:

Pengaturan dasar proyek React Native
(Pratinjau besar)

Dalam kasus kita, mari kita pilih opsi pertama untuk mengatur proyek kita sebagai dokumen kosong. Sekarang, tunggu sampai instalasi dependensi JavaScript selesai.

Setelah aplikasi kami diatur, kami dapat mengubah direktori kami ke direktori proyek baru kami dan membukanya di editor kode favorit Anda. Kita perlu menginstal perpustakaan yang akan kita gunakan untuk AsyncStorage dan perpustakaan navigasi kita. Di dalam direktori folder Anda di terminal Anda, rekatkan perintah di atas dan pilih templat ( blank akan berfungsi) untuk menginstal dependensi proyek kami.

Mari kita lihat untuk apa masing-masing dependensi ini:

  • @react-native-community/async-storage
    Seperti penyimpanan lokal di web, ini adalah React Native API untuk menyimpan data pada perangkat dalam pasangan nilai kunci.
  • @react-native-community/masked-view, react-native-screens, react-native-gesture-handle
    Dependensi ini adalah utilitas inti yang digunakan oleh sebagian besar navigator untuk membuat struktur navigasi di aplikasi. (Baca selengkapnya di Memulai navigasi React Native.)
  • @react-navigation/asli
    Ini adalah ketergantungan untuk navigasi React Native.
  • @react-navigation/stack
    Ini adalah ketergantungan untuk navigasi tumpukan di React Native.
 npm install @react-native-community/async-storage @react-native-community/masked-view @react-navigation/native @react-navigation/stack react-native-screens react-native-gesture-handle

Untuk memulai aplikasi, gunakan expo start dari direktori aplikasi di terminal Anda. Setelah aplikasi dimulai, Anda dapat menggunakan aplikasi expo dari ponsel Anda untuk memindai kode batang dan melihat aplikasi, atau jika Anda memiliki emulator android/simulator iOS, Anda dapat membuka aplikasi melaluinya dari alat pengembang expo yang terbuka di browser Anda saat Anda memulai aplikasi expo. Untuk contoh gambar dalam artikel ini, kami akan menggunakan Genymotions untuk melihat hasil kami. Inilah yang akan terlihat seperti hasil akhir kami di Genymotions:

hasil akhir di Genymotions
(Pratinjau besar)

Struktur Folder

Mari kita buat struktur folder kita dari awal sehingga lebih mudah bagi kita untuk bekerja dengannya saat kita melanjutkan:

Kita membutuhkan dua folder terlebih dahulu:

  • konteks
    Folder ini akan menyimpan konteks untuk seluruh aplikasi kami karena kami akan bekerja dengan API Konteks untuk manajemen keadaan global.
  • pemandangan
    Folder ini akan menampung folder navigasi dan tampilan untuk layar yang berbeda.

Silakan dan buat dua folder di direktori proyek Anda.

Di dalam folder konteks, buat folder bernama authContext dan buat dua file di dalam folder authContext :

  • AuthContext.js ,
  • AuthState.js .

Kita akan membutuhkan file-file ini ketika kita mulai bekerja dengan Context API.

Sekarang masuk ke folder views yang kita buat dan buat dua folder lagi di dalamnya, yaitu:

  • navigasi ,
  • layar .

Sekarang, kita belum selesai, di dalam folder layar , buat dua folder ini lagi:

  • postAuthScreens ,
  • preAuthScreens .

Jika Anda mengikuti pengaturan folder dengan benar, beginilah tampilan struktur folder Anda saat ini:

struktur folder
(Pratinjau besar)
Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Membuat Layar Pertama Kami

Sekarang mari kita buat layar pertama kita dan beri nama welcomeScreen.js di dalam folder preAuthScreens .

preAuthScreens > welcomeScreen.js

Berikut isi file welcomeScreen.js kami:

 import React from 'react'; import { View, Text, Button, StyleSheet, TextInput } from 'react-native'; const WelcomeScreen = () => { const onUserAuthentication = () => { console.log("User authentication button clicked") } return ( <View style={styles.container}> <Text style={styles.header}>Welcome to our App!</Text> <View> <TextInput style={styles.inputs} placeholder="Enter your email here.." /> <TextInput style={styles.inputs} secureTextEntry={true} placeholder="Enter your password here.." /> <Button title="AUTHENTICATE" onPress={onUserAuthentication} /> </View> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, header: { fontSize: 25, fontWeight: 'bold', marginBottom: 30 }, inputs: { width: 300, height: 40, marginBottom: 10, borderWidth: 1, } }) export default WelcomeScreen

Inilah yang kami lakukan di blok kode di atas:

Pertama, kita mengimpor hal-hal yang kita butuhkan dari perpustakaan React Native, yaitu View , Text , Button , TextInput . Selanjutnya, kami membuat komponen fungsional kami WelcomeScreen .

Anda akan melihat bahwa kami mengimpor StyleSheet dari React Native dan menggunakannya untuk mendefinisikan gaya untuk header kami dan juga <TextInput /> kami.

Terakhir, kami mengekspor komponen WelcomeScreen di bagian bawah kode.

Sekarang setelah kita selesai dengan ini, mari buat komponen ini berfungsi seperti yang diharapkan dengan menggunakan kait useState untuk menyimpan nilai input dan memperbarui statusnya kapan pun terjadi perubahan di kolom input. Kami juga akan mengimpor kait useCallback dari React karena kami akan membutuhkannya nanti untuk mengadakan fungsi.

Pertama, saat kita masih dalam komponen WelcomeScreen , kita perlu mengimpor useState dan useCallback dari React.

 import React, { useState, useCallback } from 'react';

Sekarang di dalam komponen fungsional WelcomeScreen , mari buat dua status untuk email dan kata sandi masing-masing:

 ... const WelcomeScreen = () => { const [email, setEmail] = useState('') const [password, setPassword] = useState('') return ( ... ) } ...

Selanjutnya, kita perlu memodifikasi bidang <TextInput /> kita sehingga mendapatkan nilainya dari statusnya masing-masing dan memperbarui statusnya saat nilai input diperbarui:

 import React, { useState, useCallback } from 'react'; import { View, Text, Button, StyleSheet, TextInput } from 'react-native'; const WelcomeScreen = () => { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const onInputChange = (value, setState) => { setState(value); } return ( <View> ... <View> <TextInput style={styles.inputs} placeholder="Enter your email here.." value={email} onChangeText={(value) => onInputChange(value, setEmail)} /> <TextInput style={styles.inputs} secureTextEntry={true} placeholder="Enter your password here.." value={password} onChangeText={(value) => onInputChange(value, setPassword)} /> ... </View> </View> ) } ...

Dalam kode di atas, inilah yang kami lakukan:

  • Kami membuat value dari setiap input teks untuk menunjuk ke statusnya masing-masing.
  • Kami menambahkan handler onChangeText ke input teks kami. Ini menyala kapan saja nilai baru dimasukkan atau dihapus dari bidang input.
  • Kami memanggil fungsi onInputChange kami yang menerima dua argumen:
    • value saat ini disediakan oleh handler onChangeText .
    • Penyetel status yang harus diperbarui (untuk bidang input pertama kami melewati setEmail dan yang kedua kami melewati setPassword .
    • Akhirnya, kami menulis fungsi onInputChange kami, dan fungsi kami hanya melakukan satu hal: Ini memperbarui status masing-masing dengan nilai baru.

Hal berikutnya yang perlu kita kerjakan adalah fungsi onUserAuthentication() dengan dipanggil setiap kali tombol untuk pengiriman formulir diklik.

Idealnya, pengguna harus sudah membuat akun dan login akan melibatkan semacam logika backend untuk memeriksa apakah pengguna itu ada dan kemudian memberikan token kepada pengguna. Dalam kasus kami, karena kami tidak menggunakan backend apa pun, kami akan membuat objek yang menyimpan detail login pengguna yang benar, dan kemudian hanya mengotentikasi pengguna ketika nilai yang mereka masukkan cocok dengan nilai tetap kami dari objek login email dan password yang akan kami gunakan. membuat.

Berikut kode yang perlu kita lakukan:

 ... const correctAuthenticationDetails = { email: '[email protected]', password: 'password' } const WelcomeScreen = () => { ... // This function gets called when the `AUTHENTICATE` button is clicked const onUserAuthentication = () => { if ( email !== correctAuthenticationDetails.email || password !== correctAuthenticationDetails.password ) { alert('The email or password is incorrect') return } // In here, we will handle what happens if the login details are // correct } ... return ( ... ) } ...

Salah satu hal pertama yang akan Anda perhatikan dalam kode di atas adalah bahwa kami mendefinisikan correctAuthenticationDetails (yang merupakan objek yang menyimpan detail login yang benar yang kami harapkan diberikan oleh pengguna) di luar komponen fungsional WelcomeScreen() .

Selanjutnya, kami menulis konten fungsi onUserAuthentication() dan menggunakan pernyataan bersyarat untuk memeriksa apakah email atau password yang disimpan di masing-masing status tidak cocok dengan yang kami berikan di objek kami.

Jika Anda ingin melihat apa yang telah kami lakukan sejauh ini, impor komponen WelcomeScreen ke App.js Anda seperti ini:

Buka file App.js dan letakkan ini ganti seluruh kode dengan ini:

 import { StatusBar } from 'expo-status-bar'; import React from 'react'; import { View } from 'react-native'; import WelcomeScreen from './views/screens/preAuthScreens/welcomeScreen'; export default function App() { return ( <View> <StatusBar /> <WelcomeScreen /> </View> ); }

Melihat lebih dekat pada kode di atas, Anda akan melihat bahwa apa yang kami lakukan adalah mengimpor komponen WelcomeScreen dan kemudian menggunakannya dalam fungsi App() .

Begini tampilan hasil WelcomeScreen kami:

hasil WelcomeScreen
(Pratinjau besar)

Sekarang setelah kita selesai membangun komponen WelcomeScreen , mari kita lanjutkan dan mulai bekerja dengan Context API untuk mengelola status global kita.

Mengapa API Konteks?

Dengan menggunakan API Konteks, kita tidak perlu menginstal pustaka tambahan apa pun ke dalam ReactJS, pengaturannya tidak terlalu menegangkan, dan merupakan salah satu cara paling populer untuk menangani keadaan global di ReactJS. Untuk manajemen status ringan, ini adalah pilihan yang baik.

Menciptakan Konteks Kami

Jika Anda ingat, kami membuat folder konteks sebelumnya dan membuat subfolder di dalamnya yang disebut authContext .

Sekarang mari navigasikan ke file AuthContext.js di folder authContext dan buat konteks kita:

konteks > authContext > AuthContext.js

 import React, { createContext } from 'react'; const AuthContext = createContext(); export default AuthContext;

AuthContext yang baru saja kita buat menyimpan nilai status loading dan nilai status userToken . Saat ini, di createContext yang kami deklarasikan di blok kode di atas, kami tidak menginisialisasi nilai default apa pun di sini sehingga konteks kami saat ini undefined . Contoh nilai konteks autentikasi dapat berupa {loading: false, userToken: 'abcd}

File AuthState.js menyimpan logika API Konteks dan nilai statusnya. Fungsi yang ditulis di sini dapat dipanggil dari mana saja di aplikasi kami dan ketika mereka memperbarui nilai dalam status, itu juga diperbarui secara global.

Pertama, mari kita bawa semua impor yang kita perlukan ke dalam file ini:

konteks > AuthContext > AuthState.js

 import React, { useState } from 'react'; import AuthContext from './AuthContext'; import AsyncStorage from '@react-native-community/async-storage';

Kami mengimpor kait useState() dari ReactJS untuk menahan status kami, kami mengimpor file AuthContext yang kami buat di atas karena di sinilah konteks kosong kami untuk otentikasi diinisialisasi dan kami perlu menggunakannya seperti yang akan Anda lihat nanti saat kami maju , akhirnya kita mengimpor paket AsyncStorage (mirip dengan localStorage untuk web).

AsyncStorage adalah React Native API yang memungkinkan Anda menyimpan data secara offline melalui perangkat dalam aplikasi React Native.

 ... const AuthState = (props) => { const [userToken, setUserToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const onAuthentication = async() => { const USER_TOKEN = "drix1123q2" await AsyncStorage.setItem('user-token', USER_TOKEN); setUserToken(USER_TOKEN); console.warn("user has been authenticated!") } return ( <AuthContext.Provider value={{ onAuthentication, }} > {props.children} </AuthContext.Provider> ) } export default AuthState;

Di blok kode di atas, inilah yang kami lakukan:

  • Kami mendeklarasikan dua status untuk userToken dan isLoading . userToken akan digunakan untuk menyimpan token yang disimpan ke AsyncStorage , sedangkan status isLoading akan digunakan untuk melacak status pemuatan (awalnya disetel ke true ). Kami akan mencari tahu lebih banyak tentang penggunaan kedua status ini saat kami melanjutkan.

  • Selanjutnya, kami menulis fungsi onAuthentication() kami. Fungsi ini adalah fungsi async yang dipanggil saat tombol login diklik dari file welcomeScreen.jsx . Fungsi ini hanya akan dipanggil jika email dan kata sandi yang diberikan pengguna cocok dengan objek detail pengguna yang benar yang kami berikan. Biasanya yang terjadi selama otentikasi adalah bahwa token dibuat untuk pengguna setelah pengguna diautentikasi di backend menggunakan paket seperti JWT, dan token ini dikirim ke frontend. Karena kita tidak akan membahas semua itu untuk tutorial ini, kita membuat token statis dan menyimpannya dalam variabel yang disebut USER_TOKEN .

  • Selanjutnya, kita menggunakan kata kunci await untuk mengatur token pengguna kita ke AsyncStorage dengan nama user-token . Pernyataan console.warn() hanya digunakan untuk memeriksa apakah semuanya berjalan dengan baik, Anda dapat melepasnya kapan pun Anda mau.

  • Terakhir, kami meneruskan fungsi onAuthenticated kami sebagai nilai di dalam <AuthContext.Provider> kami sehingga kami dapat mengakses dan memanggil fungsi tersebut dari mana saja di aplikasi kami.

screens > preAuth > welcomeScreen.js

Pertama, impor useContext dari ReactJS dan impor AuthContext dari file AuthContext.js .

 import React, { useState, useContext } from 'react'; import AuthContext from '../../../context/authContext/AuthContext' ...

Sekarang, di dalam komponen fungsional welcomeScreen() , mari gunakan konteks yang telah kita buat:

 ... const WelcomeScreen = () => { const { onAuthentication } = useContext(AuthContext) const onUserAuthentication = () => { if ( email !== correctAuthenticationDetails.email || password !== correctAuthenticationDetails.password ) { alert('The email or password is incorrect') return } onAuthentication() } return ( ... ) } ...

Dalam blok kode di atas, kami mendestruktur fungsi onAuthentication dari AuthContext kami dan kemudian kami memanggilnya di dalam fungsi onUserAuthentication() kami dan menghapus pernyataan console.log() yang ada sebelumnya sekarang.

Saat ini, ini akan menimbulkan kesalahan karena kami belum memiliki akses ke AuthContext . Untuk menggunakan AuthContext di mana saja di aplikasi Anda, kami perlu membungkus file tingkat atas di aplikasi kami dengan AuthState (dalam kasus kami, ini adalah file App.js ).

Buka file App.js dan ganti kode di sana dengan ini:

 import React from 'react'; import WelcomeScreen from './views/screens/preAuthScreens/welcomeScreen'; import AuthState from './context/authContext/AuthState' export default function App() { return ( <AuthState> <WelcomeScreen /> </AuthState> ); }

Kita sudah sampai sejauh ini dan kita sudah selesai dengan bagian ini. Sebelum kita pindah ke bagian berikutnya di mana kita mengatur perutean kita, mari buat layar baru. Layar yang akan kita buat akan menjadi file HomeScreen.js yang seharusnya muncul hanya setelah otentikasi berhasil.

Buka: layar > postAuth .

Buat file baru bernama HomeScreen.js . Berikut kode untuk file HomeScreen.js :

layar > postAuth > Layar Beranda.js

 import React from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; const HomeScreen = () => { const onLogout = () => { console.warn("Logout button cliked") } return ( <View style={styles.container}> <Text>Now you're authenticated! Welcome!</Text> <Button title="LOG OUT" onPress={onLogout} /> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, }) export default HomeScreen

Untuk saat ini, tombol logout memiliki pernyataan dummy console.log() . Nanti, kita akan membuat fungsi logout dan meneruskannya ke layar dari konteks kita.

Menyiapkan Rute Kami

Kita perlu membuat tiga (3) file di dalam folder navigasi kita:

  • postAuthNavigator.js ,
  • preAuthNavigator.js ,
  • AppNavigator.js .

Setelah Anda membuat ketiga file ini, navigasikan ke file preAuthNaviagtor.js yang baru saja Anda buat dan tulis ini:

navigasi > preAuthNavigator.js

 import React from "react"; import { createStackNavigator } from "@react-navigation/stack"; import WelcomeScreen from "../screens/preAuthScreens/welcomeScreen"; const PreAuthNavigator = () => { const { Navigator, Screen } = createStackNavigator(); return ( <Navigator initialRouteName="Welcome"> <Screen name="Welcome" component={WelcomeScreen} /> </Navigator> ) } export default PreAuthNavigator;

Dalam file di atas, inilah yang kami lakukan:

  • Kami mengimpor createStackNavigator dari @react-navigation/stack yang kami gunakan untuk navigasi tumpukan kami. createStackNavigator Menyediakan cara bagi aplikasi Anda untuk bertransisi antar layar di mana setiap layar baru ditempatkan di atas tumpukan. Secara default, navigator tumpukan dikonfigurasi untuk memiliki tampilan & nuansa iOS dan Android yang familier: layar baru meluncur dari kanan di iOS, memudar dari bawah di Android. Klik di sini jika Anda ingin mempelajari lebih lanjut tentang navigator tumpukan di React Native.
  • Kami mendestruktur Navigator dan Screen dari createStackNavigator() .
  • Dalam pernyataan pengembalian kami, kami membuat navigasi kami dengan <Navigator/> dan membuat layar kami dengan <Screen/> . ini berarti bahwa jika kita memiliki beberapa layar yang dapat diakses sebelum otentikasi, kita akan memiliki beberapa <Screen/> di sini yang mewakilinya.
  • Terakhir, kami mengekspor komponen PreAuthNavigator kami.

Mari kita lakukan hal serupa untuk file postAuthNavigator.js .

navigasi > postAuthNavigator.js

 import React from "react"; import { createStackNavigator } from "@react-navigation/stack"; import HomeScreen from "../screens/postAuthScreens/HomeScreen"; const PostAuthNavigator = () => { const { Navigator, Screen} = createStackNavigator(); return ( <Navigator initialRouteName="Home"> <Screen name="Home" component={HomeScreen} /> </Navigator> ) } export default PostAuthNavigator;

Seperti yang kita lihat pada kode di atas, satu-satunya perbedaan antara preAuthNavigator.js dan postAuthNavigator.js adalah layar yang dirender. Sementara yang pertama mengambil WelcomeScreen , postAuthNavigator.js mengambil HomeScreen .

Untuk membuat AppNavigator.js kita, kita perlu membuat beberapa hal.

Karena AppNavigator.js adalah tempat kita akan beralih dan memeriksa rute mana yang akan tersedia untuk diakses oleh pengguna, kita memerlukan beberapa layar agar ini berfungsi dengan baik, mari kita uraikan hal-hal yang perlu kita buat terlebih dahulu:

  1. Layar Transisi.js
    Sementara aplikasi memutuskan navigasi mana yang akan dipasang, kami ingin layar transisi muncul. Biasanya, layar transisi akan menjadi pemintal pemuatan atau animasi khusus lainnya yang dipilih untuk aplikasi, tetapi dalam kasus kami, kami akan menggunakan <Text/> dasar untuk menampilkan loading… .
  2. checkAuthenticationStatus()
    Fungsi inilah yang akan kita panggil untuk memeriksa status otentikasi yang akan menentukan tumpukan navigasi mana yang akan dipasang. Kami akan membuat fungsi ini dalam konteks kami dan menggunakannya di Appnavigator.js .

Sekarang, mari kita buat file TransitionScreen.js kita.

layar > TransitionScreen.js

 import React from 'react'; import { Text, View } from 'react-native'; const TransitionScreen = () => { return ( <View> <Text>Loading...</Text> </View> ) } export default TransitionScreen

Layar transisi kami hanyalah layar sederhana yang menampilkan pemuatan teks. Kami akan melihat di mana menggunakan ini saat kami melanjutkan di artikel ini.

Selanjutnya, mari kita buka AuthState.js dan tulis checkAuthenticationStatus() :

konteks > authContext > AuthState.js

 import React, { useState, useEffect } from 'react'; import AuthContext from './AuthContext'; import AsyncStorage from '@react-native-community/async-storage'; const AuthState = (props) => { const [userToken, setUserToken] = useState(null); const [isLoading, setIsLoading] = useState(true); ... useEffect(() => { checkAuthenticationStatus() }, []) const checkAuthenticationStatus = async () => { try { const returnedToken = await AsyncStorage.getItem('user-toke n'); setUserToken(returnedToken); console.warn('User token set to the state value) } catch(err){ console.warn(`Here's the error that occured while retrievin g token: ${err}`) } setIsLoading(false) } const onAuthentication = async() => { ... } return ( <AuthContext.Provider value={{ onAuthentication, userToken, isLoading, }} > {props.children} </AuthContext.Provider> ) } export default AuthState;

Pada blok kode di atas, kita menulis fungsi checkAuthenticationStatus() . Dalam fungsi kami, inilah yang kami lakukan:

  • Kami menggunakan kata kunci await untuk mendapatkan token kami dari AsyncStorage . Dengan AsyncStorage , jika tidak ada token yang diberikan, ia mengembalikan null . userToken awal kami juga disetel ke null .
  • Kami menggunakan setUserToken untuk menetapkan nilai yang dikembalikan dari AsyncStorage sebagai userToken baru kami. Jika nilai yang dikembalikan adalah null , itu berarti userToken kita tetap null .
  • Setelah blok try{}…catch(){} , kita menyetel isLoading ke false karena fungsi untuk memeriksa status autentikasi telah selesai. Kita membutuhkan nilai isLoading untuk mengetahui apakah kita masih harus menampilkan TransitionScreen atau tidak. Sebaiknya pertimbangkan untuk menetapkan kesalahan jika ada kesalahan saat mengambil token sehingga kami dapat menampilkan tombol "Coba Lagi" atau "Coba Lagi" kepada pengguna saat kesalahan ditemukan.
  • Setiap kali AuthState dipasang, kami ingin memeriksa status otentikasi, jadi kami menggunakan useEffect() ReactJS untuk melakukan ini. Kami memanggil fungsi checkAuthenticationStatus() kami di dalam kait useEffect() dan menyetel nilai isLoading ke false setelah selesai.
  • Terakhir, kami menambahkan status kami ke nilai <AuthContext.Provider/> kami sehingga kami dapat mengaksesnya dari mana saja di aplikasi kami yang dicakup oleh Context API.

Sekarang kita memiliki fungsi kita, sekarang saatnya untuk kembali ke AppNavigator.js kita dan menulis kode untuk memasang navigator tumpukan tertentu berdasarkan status otentikasi:

navigasi > AppNavigator.js

Pertama, kita akan mengimpor semua yang kita butuhkan untuk AppNavigator.js kita.

 import React, { useEffect, useContext } from "react"; import PreAuthNavigator from "./preAuthNavigator"; import PostAuthNavigator from "./postAuthNavigator"; import { NavigationContainer } from "@react-navigation/native" import { createStackNavigator } from "@react-navigation/stack"; import AuthContext from "../../context/authContext/AuthContext"; import TransitionScreen from "../screens/TransitionScreen";

Sekarang setelah kita memiliki semua impor, mari buat fungsi AppNavigator() .

 ... const AppNavigator = () => { } export default AppNavigator

Selanjutnya, sekarang kita akan melanjutkan untuk menulis konten fungsi AppNavigator() kita:

 import React, { useState, useEffect, useContext } from "react"; import PreAuthNavigator from "./preAuthNavigator"; import PostAuthNavigator from "./postAuthNavigator"; import { NavigationContainer } from "@react-navigation/native" import { createStackNavigator } from "@react-navigation/stack"; import AuthContext from "../../context/authContext/AuthContext"; import TransitionScreen from "../screens/transition"; const AppNavigator = () => { const { Navigator, Screen } = createStackNavigator(); const authContext = useContext(AuthContext); const { userToken, isLoading } = authContext; if(isLoading) { return <TransitionScreen /> } return ( <NavigationContainer> <Navigator> { userToken == null ? ( <Screen name="PreAuth" component={PreAuthNavigator} options={{ header: () => null }} /> ) : ( <Screen name="PostAuth" component={PostAuthNavigator} options={{ header: () => null }} /> ) } </Navigator> </NavigationContainer> ) } export default AppNavigator

Di blok kode di atas, inilah garis besar dari apa yang kami lakukan:

  • Kami membuat navigator tumpukan dan merusak Navigator dan Screen darinya.
  • Kami mengimpor userToken dan isLoading dari AuthContext kami
  • Saat AuthState dipasang, checkAuthenticationStatus() dipanggil di kait useEffecct di sana. Kami menggunakan pernyataan if untuk memeriksa apakah isLoading true , jika true layar yang kami kembalikan adalah <TransitionScreen /> kami yang kami buat sebelumnya karena fungsi checkAuthenticationStatus() belum selesai.
  • Setelah checkAuthenticationStatus() kami selesai, isLoading disetel ke false dan kami mengembalikan komponen Navigasi utama kami.
  • NavigationContainer diimpor dari @react-navigation/native . Ini hanya digunakan sekali di navigator tingkat atas utama. Perhatikan bahwa kita tidak menggunakan ini di preAuthNavigator.js atau postAuthNavigator.js.
  • Di AppNavigator() kami, kami masih membuat navigator tumpukan. Jika userToken yang didapat dari API Konteks kami adalah null , kami memasang PreAuthNavigator , jika nilainya adalah sesuatu yang lain (artinya AsyncStorage.getItem() di checkAuthenticationStatus() mengembalikan nilai aktual), lalu kami memasang PostAuthNavigator . Render bersyarat kami dilakukan menggunakan operator ternary.

Sekarang kami telah menyiapkan AppNavigator.js kami. Selanjutnya, kita perlu meneruskan AppNavigator kita ke file App.js kita.

Mari kita berikan AppNavigator kita ke file App.js :

aplikasi.js

 ... import AppNavigator from './views/navigation/AppNavigator'; ... return ( <AuthState> <AppNavigator /> </AuthState> );

Sekarang mari kita lihat seperti apa tampilan aplikasi kita saat ini:

Inilah yang terjadi ketika Anda memberikan kredensial yang salah saat mencoba masuk:

Menambahkan Fungsi Logout

Pada titik ini, proses otentikasi dan pemilihan rute kami selesai. Satu-satunya yang tersisa untuk aplikasi kita adalah menambahkan fungsi logout.

Tombol logout ada di file HomeScreen.js . Kami meneruskan fungsi onLogout() ke atribut onPress dari tombol. Untuk saat ini, kami memiliki pernyataan console.log() sederhana dalam fungsi kami, tetapi dalam beberapa saat itu akan berubah.

Sekarang, mari buka AuthState.js kita dan tulis fungsi untuk logout. Fungsi ini hanya menghapus AsyncStorage tempat token pengguna disimpan.

konteks > authContext > AuthState.js

 ... const AuthState = (props) => { ... const userSignout = async() => { await AsyncStorage.removeItem('user-token'); setUserToken(null); } return ( ... ) } export default AuthState;

userSignout() adalah fungsi asinkron yang menghapus user-token dari AsyncStorage kami.

Sekarang kita perlu memanggil fungsi userSignout() di HomeScreen.js kita setiap kali tombol logout diklik.

Mari pergi ke HomeScreen.js kita dan gunakan userSignout() dari AuthContext kita.

layar > postAuthScreens > HomeScreen.js

 import React, { useContext } from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; import AuthContext from '../../../context/authContext/AuthContext' const HomeScreen = () => { const { userSignout } = useContext(AuthContext) const onLogout = () => { userSignout() } return ( <View style={styles.container}> <Text>Now you're authenticated! Welcome!</Text> <Button title="LOG OUT" onPress={onLogout} /> </View> ) } ...

Di blok kode di atas kami mengimpor Anda useContext hook dari ReactJS, lalu kami mengimpor AuthContext. Selanjutnya, kami mendestruktur fungsi userSignout dari AuthContext kami dan fungsi userSignout() ini dipanggil dalam fungsi onLogout() kami.

Sekarang setiap kali tombol logout kami diklik, token pengguna di AsyncStorage kami dihapus.

Voila! seluruh proses kami selesai.

Inilah yang terjadi ketika Anda menekan tombol kembali setelah Anda masuk:

Menekan tombol kembali setelah masuk ke aplikasi.

Inilah yang terjadi ketika Anda menekan tombol kembali setelah keluar:

Menekan tombol kembali setelah keluar dari aplikasi.

Berikut adalah beberapa perilaku berbeda yang kami perhatikan saat menggunakan pola ini dalam pengalihan tumpukan navigasi kami:

  1. Anda akan melihat bahwa tidak ada tempat untuk menggunakan navigation.navigate() atau navigation.push() untuk pergi ke rute lain setelah login. Setelah status kami diperbarui dengan token pengguna, tumpukan navigasi yang diberikan secara otomatis berubah.
  2. Menekan tombol kembali pada perangkat Anda setelah login berhasil tidak dapat membawa Anda kembali ke halaman login, sebaliknya, menutup aplikasi sepenuhnya. Perilaku ini penting karena Anda tidak ingin pengguna dapat kembali ke halaman login kecuali mereka logout dari aplikasi. Hal yang sama berlaku untuk logout — setelah pengguna logout, mereka tidak dapat menggunakan tombol kembali untuk kembali ke layar HomeScreen , tetapi sebaliknya, aplikasi ditutup.

Kesimpulan

Di banyak Aplikasi, autentikasi adalah salah satu bagian terpenting karena mengonfirmasi bahwa orang yang mencoba mendapatkan akses ke konten yang dilindungi memiliki hak untuk mengakses informasi. Mempelajari cara melakukannya dengan benar adalah langkah penting dalam membangun aplikasi yang hebat, intuitif, dan mudah digunakan/navigasi.

Membangun di atas kode ini, berikut adalah beberapa hal yang mungkin Anda pertimbangkan untuk ditambahkan:

  • Validasi formulir untuk memvalidasi bidang input. Lihat validasi formulir React Native dengan Formik dan Yup.
  • Otentikasi Firebase untuk mengintegrasikan autentikasi dengan Gmail, Github, Facebook, Twitter, atau antarmuka khusus Anda. Lihat React Native Firebase.
  • Konsep kode untuk desainer: Otentikasi dan Otorisasi.

Berikut ini juga beberapa sumber penting yang saya temukan yang akan mencerahkan Anda lebih banyak tentang otentikasi, keamanan, dan cara melakukannya dengan benar:

Sumber daya

  • Bereaksi Asli: Alur Otentikasi Pengguna Dijelaskan
  • 10 Praktik Terbaik Keamanan Bereaksi
  • Metode Otentikasi yang Dapat Mencegah Pelanggaran Berikutnya
  • Lihat build/pratinjau langsung aplikasi kami di sini;
  • Lihat proyek di GitHub.