ProductPromotion
Logo

0x3d.Site

is designed for aggregating information.

Authentication

Now that your React Native app is up and running and can communicate with your Node.js backend, it's time to add a layer of security—authentication. Imagine your app is a cozy little café; you wouldn't want just anyone walking in without a valid reason. Authentication ensures that only the right people have access to your app's features and data.

In this chapter, we’ll dive into user authentication by implementing a simple login and registration system. We’ll use JSON Web Tokens (JWT) for secure communication between the client and server. Don't worry if that sounds complicated; we'll break it down step by step.

By the end of this chapter, your app will allow users to register, log in, and access protected routes. Let’s get started!

Step 1: Setting Up User Registration and Login Routes in Node.js

First, we need to set up the backend to handle user registration and login. This involves creating new routes in your Node.js application that will accept user credentials, verify them, and respond accordingly.

Installing Required Packages

Before we dive into coding, let’s install a couple of packages. Open your terminal and run the following command:

npm install bcryptjs jsonwebtoken
  • bcryptjs: This package will help us hash user passwords before storing them, making it much harder for anyone to steal passwords.
  • jsonwebtoken: This will allow us to create and verify JWTs for our authentication system.

Creating Registration and Login Routes

Open your server.js (or whichever file you’re using to set up your server) and add the following code to create the routes:

const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

const app = express();
const PORT = 3000;
const SECRET_KEY = 'your-secret-key'; // Change this to something more secure

app.use(express.json());

let users = []; // Simulated database for users

// Registration Route
app.post('/register', async (req, res) => {
  const { name, email, password } = req.body;

  // Check if user already exists
  const existingUser = users.find(user => user.email === email);
  if (existingUser) {
    return res.status(400).json({ message: 'User already exists' });
  }

  // Hash password
  const hashedPassword = await bcrypt.hash(password, 10);

  // Create new user and add to database
  const newUser = { name, email, password: hashedPassword };
  users.push(newUser);

  res.status(201).json({ message: 'User registered successfully' });
});

// Login Route
app.post('/login', async (req, res) => {
  const { email, password } = req.body;

  // Find user by email
  const user = users.find(user => user.email === email);
  if (!user) {
    return res.status(400).json({ message: 'Invalid email or password' });
  }

  // Verify password
  const isPasswordValid = await bcrypt.compare(password, user.password);
  if (!isPasswordValid) {
    return res.status(400).json({ message: 'Invalid email or password' });
  }

  // Generate JWT token
  const token = jwt.sign({ email: user.email }, SECRET_KEY, { expiresIn: '1h' });
  res.status(200).json({ token });
});

// Start the server
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

Explanation:

  1. User Registration:

    • The /register route accepts a POST request with user details.
    • It checks if the user already exists by looking for their email.
    • If not, it hashes the password and stores the new user in our simulated database.
  2. User Login:

    • The /login route checks if the user exists and verifies the password using bcrypt.
    • If the password is correct, it generates a JWT token using the user's email and sends it back to the client.

Step 2: Adding Authentication to Your React Native App

Now that the backend is set up, let’s modify your React Native app to allow users to register and log in.

Updating Your App to Include Registration and Login Forms

Open your App.js file and update it to include registration and login forms. Here’s the updated code:

import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button, FlatList, Alert } from 'react-native';
import axios from 'axios';

export default function App() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [token, setToken] = useState('');

  const registerUser = () => {
    axios.post('http://192.168.x.x:3000/register', { name, email, password })
      .then(response => {
        Alert.alert('Success', response.data.message);
        setName('');
        setEmail('');
        setPassword('');
      })
      .catch(error => {
        Alert.alert('Error', error.response.data.message);
      });
  };

  const loginUser = () => {
    axios.post('http://192.168.x.x:3000/login', { email, password })
      .then(response => {
        setToken(response.data.token);
        setIsLoggedIn(true);
        Alert.alert('Success', 'Logged in successfully');
      })
      .catch(error => {
        Alert.alert('Error', error.response.data.message);
      });
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>User Authentication</Text>

      {isLoggedIn ? (
        <View>
          <Text style={styles.welcome}>Welcome!</Text>
          <Text>Your token: {token}</Text>
        </View>
      ) : (
        <View>
          <TextInput
            style={styles.input}
            placeholder="Enter name"
            value={name}
            onChangeText={setName}
          />
          <TextInput
            style={styles.input}
            placeholder="Enter email"
            value={email}
            onChangeText={setEmail}
          />
          <TextInput
            style={styles.input}
            placeholder="Enter password"
            value={password}
            onChangeText={setPassword}
            secureTextEntry
          />
          <Button title="Register" onPress={registerUser} />
          <Button title="Login" onPress={loginUser} />
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingTop: 50,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  input: {
    width: '80%',
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 10,
    paddingHorizontal: 10,
  },
  welcome: {
    fontSize: 20,
    fontWeight: 'bold',
  },
});

Breakdown of Changes:

  1. State Variables:

    • Added state variables for name, password, isLoggedIn, and token.
  2. Registration and Login Functions:

    • registerUser function sends user data to the backend for registration.
    • loginUser function sends email and password to log in and retrieves the JWT token.
  3. Conditional Rendering:

    • The UI switches between registration/login forms and a welcome message based on the isLoggedIn state.

Step 3: Storing the Token Securely

For security, it’s important to store the JWT token securely on the device. We’ll use the AsyncStorage library for this purpose. Install it by running:

npm install @react-native-async-storage/async-storage

Next, import AsyncStorage in your App.js:

import AsyncStorage from '@react-native-async-storage/async-storage';

Now, update the loginUser function to save the token:

const loginUser = () => {
  axios.post('http://192.168.x.x:3000/login', { email, password })
    .then(response => {
      const userToken = response.data.token;
      setToken(userToken);
      setIsLoggedIn(true);
      AsyncStorage.setItem('userToken', userToken); // Store token securely
      Alert.alert('Success', 'Logged in successfully');
    })
    .catch(error => {
      Alert.alert('Error', error.response.data.message);
    });
};

To retrieve the token when the app starts, you can add the following code inside a useEffect hook:

import { useEffect } from 'react';

useEffect(() => {
  const getToken = async () => {
    const storedToken = await AsyncStorage.getItem('userToken');
    if (storedToken) {
      setToken(storedToken);
      setIsLoggedIn(true);
    }
  };

  getToken();
}, []);

This code checks for a stored token when the app loads and sets the user to logged in if a valid token exists.

Step 4: Protecting Routes in Node.js

Now that your React Native app can authenticate users, let’s protect your Node.js routes. We want to ensure that certain routes are only accessible if the user is logged in. We’ll create a middleware function to do this.

Add the following middleware function to your server.js file:

const authenticateToken = (req, res, next) => {
  const token = req.headers['authorization']?.split(' ')[1];
  if (!token) return res.sendStatus(401); // Unauthorized

  jwt.verify(token, SECRET_KEY, (err, user) => {
    if (err) return res.sendStatus(403); // Forbidden
    req.user = user;
    next();
  });
};

// Example protected route
app.get('/protected', authenticateToken, (req, res) => {
  res.json({ message: 'This is protected data!', user: req.user });
});

Explanation of the Middleware:

  • authenticateToken: This function checks for a token in the request headers. If there’s no token, it sends a 401 status.
  • If a token is present, it verifies it. If valid, it allows access to the next route; if not, it sends a 403 status.

You can test the protected route by sending a GET request to /protected with the token in the authorization header.

Step 5: Enhancing User Experience with Logout

Finally, let’s add a logout feature to your app. This is a good way to let users end their session.

Add a logoutUser function in your App.js:

const logoutUser = async () => {
  await AsyncStorage.removeItem('userToken'); // Remove token
  setIsLoggedIn(false); // Set logged in state to false
  setToken(''); // Clear token
  Alert.alert('Success', 'Logged out successfully');
};

You can add a button to call this function when users want to log out:

<Button title="Logout" onPress={logoutUser} />

Now, when the user logs out, the app clears the token and sets the user state back to logged out.

Step 6: Testing Your Authentication System

Now that everything is set up, it’s time to test your authentication system!

  1. Start your Node.js server by running node server.js.
  2. Open your React Native app.
  3. Try registering a new user and then logging in with that user.
  4. After logging in, test accessing protected routes using tools like Postman or directly from your app.
  5. Don’t forget to test logging out and ensuring everything works as expected.

Step 7: Wrapping Up

Congratulations! You’ve now added user authentication to your React Native app with Node.js. This chapter laid the groundwork for building secure applications that handle user data responsibly.

In the next chapter, we’ll dive even deeper and explore how to integrate a database to store user information persistently. This way, your user data won’t disappear when the server restarts.

🚀

Cross-Platform Mobile App with Node.js and React Native

Learn to build a cross-platform mobile app with Node.js and React Native in this easy-to-follow course. You’ll set up your backend, design a user-friendly interface, add authentication, and deploy your app to the cloud. Packed with hands-on tutorials and practical tips, this course helps you gather user feedback, optimize performance, and effectively market your app. Perfect for beginners, this guide will give you the skills to bring your app ideas to life!
  1. Collections 😎
  2. Frequently Asked Question's 🤯
  3. Shortcuts 🥱
  4. Error Solutions 🤬
  5. Programming Tips & Tricks 🥸

Tools

available to use.

Providers

to have an visit.

Made with ❤️

to provide resources in various ares.
  1. Home
  2. About us
  3. Contact us
  4. Privacy Policy
  5. Terms and Conditions

Resouces

to browse on more.
0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory