Build a great login experience with React Native, Axios and JSONWebToken
We Have to Done Following steps.
- We want a backend API
- We want react-native project Version: 0.60 or up
- We will use JSON web token
- Axios
- React-native navigation Version: 6.x
- Stack navigation
- AsyncStroge
Maybe that’s enough for this
Let’s start our project.
Make our project by using following command
npx react-native init Athentication_belog
Here is your new project looks like
Now go to your terminal and write following command in your terminal.
cd Athentication_belog
After this now install react native navigation by using
yarn add @react-navigation/native
Or if you are using npm then use following command
npm install @react-navigation/native
following is the official link of react-native navigation
https://reactnavigation.org/docs/getting-started
we also need to install following dependencies
yarn add react-native-screens react-native-safe-area-context
Or if you are using npm then use following command
npm install react-native-screens react-native-safe-area-context
for using navigation, you have to edit
your MainActicity.java Which is located android/app/src/main/java/<your package name>/MainActivity.java.
Add the following code to the body of MainActivity class:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
and make sure to add the following import statement at the top of this file below your package statement:
import android.os.Bundle;
now install react-native stack dependency
yarn add @react-navigation/native-stack
now run your application using
npx react-native run-android
and in another terminal
npx react-native start
your android screen looks like
Now clean up your App.js and add the following code.
import React from 'react';
import {View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
const App = () => {
return (
<View>
<NavigationContainer>
{/* Rest of your app code */}
</NavigationContainer>
</View>
);
};
export default App;
create a folder root src/ Navigation/Stack.js and paste following code
import React from 'react';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
const Stack = () => {
const Stack = createNativeStackNavigator();
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
);
};
export default Stack;
and update your App.js file with following code
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import StackScreen from './src/Navigation/Stack';
const App = () => {
return (
<NavigationContainer>
<StackScreen />
</NavigationContainer>
);
};
export default App;
Now Create Screens Screen/Home/Home.js and put the code
import React from 'react';
import {View, Text, Button} from 'react-native';
const HomeScreen = ({navigation}) => {
const logOutScreen = () => {
};
return (
<View
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
backgroundColor: '#FFFFFF',
width: '100%',
}}>
<Text style={{color: '#333'}}>HomeScreen</Text>
<View style={{marginTop: 10}}>
<Button title="logOut" onPress={logOutScreen} />
</View>
</View>
);
};
export default HomeScreen;
create further files for login Screens/Login/Login.js
import {
View,
Text,
Alert,
TouchableOpacity,
Image,
TextInput,
ScrollView,
SafeAreaView,
StatusBar,
StyleSheet,
} from 'react-native';
import React, {useState} from 'react';
const Login = ({navigation}) => {
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const submit = () => {
axios
.post(your api here', {
username: username,
password: password,
})
.then(async res => {
await AsyncStorage.setItem('userToken', JSON.stringify(res.data));
navigation.navigate('Home');
})
.catch(error => alert());
};
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollView}>
<View style={styles.mainContainer}>
<View style={styles.mainImage}>
<Text style={styles.image}>Log in</Text>
</View>
<Text style={styles.mainHeader}>Login Form</Text>
<Text style={styles.description}>
This is first test for login Form
</Text>
<View style={styles.input}>
<Text style={styles.label}>Enter Your Name </Text>
<TextInput
value={userName}
onChangeText={actual => setUserName(actual)}
style={styles.inputStyle}
autoCapitalize="none"
autoCorrect={false}
/>
</View>
<View style={styles.input}>
<Text style={styles.label}>Enter Your Password</Text>
<TextInput
value={password}
onChangeText={actual => setPassword(actual)}
style={styles.inputStyle}
autoCapitalize="none"
autoCorrect={false}
secureTextEntry={true}
/>
</View>
<TouchableOpacity onPress={() => submit()} style={styles.buttonStyle}>
<Text style={styles.btn}>Login</Text>
</TouchableOpacity>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
},
scrollView: {
marginHorizontal: 20,
},
mainContainer: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
paddingHorizontal: 10,
paddingTop: 30,
backgroundColor: '#fff',
},
mainHeader: {
fontSize: 25,
color: '#344055',
fontWeight: '500',
paddingTop: 20,
paddingBottom: 15,
textTransform: 'capitalize',
fontFamily: 'regular',
},
mainImage: {
display: 'flex',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: 85,
height: 85,
},
description: {
fontSize: 20,
color: '#7d7d7d',
paddingBottom: 20,
lineHeight: 25,
fontFamily: 'regular',
},
input: {
marginTop: 20,
},
label: {
fontSize: 18,
color: '#7d7d7d',
marginTop: 5,
marginBottom: 5,
lineHeight: 25,
fontFamily: 'regular',
},
inputStyle: {
width: 280,
borderWidth: 1,
borderBottomColor: 'rgb(0,0,0.3',
paddingHorizontal: 15,
padddingVertical: 7,
borderRadius: 1,
fontFamily: 'regular',
fontSize: 18,
},
checkbox: {alignSelf: 'center'},
wrapper: {},
buttonStyle: {
marginTop: 10,
backgroundColor: 'blue',
justifyContent: 'center',
width: '100%',
height: 40,
borderRadius: 5,
marginBottom: 10,
},
btn: {
fontSize: 22,
textAlign: 'center',
color: 'white',
},
});
export default Login;
Here we are saving the JWT in AsyncStorage
Now create a custom Hook for Hooks/Auth.js file like so
import React, {useEffect, useState} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {useNavigation} from '@react-navigation/native';
const useAuth = () => {
const navigation = useNavigation();
const [data, setData] = useState();
const readData = async () => {
try {
const value = await AsyncStorage.getItem('userToken');
if (value !== null) {
const parseData = JSON.parse(value);
setData(parseData);
} else {
navigation.navigate('SignIn');
}
} catch (e) {
alert('Failed to fetch the input from storage');
}
};
useEffect(() => {
readData();
}, []);
return data;
};
export default useAuth;
Lastly only call the useAuth hook where you want to apply authentication
Like we are applying in Home.js file
const HomeScreen = ({navigation}) => {
useAuth();
const logOutPress = async () => {
try {
await AsyncStorage.clear();
alert('Storage successfully cleared!');
navigation.navigate('SignIn');
} catch (e) {
alert('Failed to clear the async storage.');
}
};
return (
<View
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
backgroundColor: '#FFFFFF',
width: '100%',
}}>
<Text style={{color: '#333'}}>HomeScreen</Text>
<View style={{marginTop: 10}}>
<Button title="logOutScreen" onPress={ logOutPress} />
</View>
</View>
);
};
export default HomeScreen;
And for logout we clear the AsyncStorage JWT and when we clear it return us to login Page.
Happy coding!