,

User Authentication with MERN Stack | MongoDB, Express, React, and Node Login and Signup

Posted by

In this tutorial, we will be creating a user authentication system using the MERN stack, which includes MongoDB, Express, React, and Node.js. We will be implementing both login and signup functionalities for users to access our application.

Step 1: Setting up the Backend

First, we need to set up our backend using Node.js and Express. Let’s start by creating a new project folder and navigating into it in your terminal:

mkdir backend
cd backend

Next, let’s initialize a new Node.js project by running the following command:

npm init -y

Now, let’s install the necessary dependencies for our backend. We will be using express, mongoose, bcrypt, and jsonwebtoken:

npm install express mongoose bcrypt jsonwebtoken

Next, let’s create a new server.js file in our project folder and set up our Express server:

const express = require('express');
const mongoose = require('mongoose');

const app = express();

// Connect to MongoDB
mongoose.connect('mongodb://localhost/authDemo', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.error('Could not connect to MongoDB', err));

app.use(express.json());

// Routes
app.use('/api/auth', require('./routes/auth'));

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

Now, let’s create a new folder called routes in our backend folder and create a new auth.js file inside it. This file will contain our authentication routes:

const router = require('express').Router();

router.post('/signup', async (req, res) => {
  // Signup logic here
});

router.post('/login', async (req, res) => {
  // Login logic here
});

module.exports = router;

Step 2: Setting up MongoDB

Before we can test our authentication system, we need to set up a MongoDB database. You can install MongoDB locally or use a cloud-based service like MongoDB Atlas. Make sure you have your MongoDB connection URI ready to connect to your database.

Step 3: Implementing Signup and Login Functionality

Now, let’s implement the signup and login functionality in our backend. We will be using the bcrypt library to hash passwords and jsonwebtoken for generating and verifying JWT tokens.

In the auth.js file, let’s implement the signup logic:

const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const User = require('../models/User');

router.post('/signup', async (req, res) => {
  try {
    const { username, email, password } = req.body;

    // Check if user already exists
    let user = await User.findOne({ email });
    if (user) return res.status(400).json({ message: 'User already exists' });

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

    // Create a new user
    user = new User({ username, email, password: hashedPassword });
    await user.save();

    res.json({ message: 'User created successfully' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Server error' });
  }
});

Now, let’s implement the login logic in the auth.js file:

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

    // Check if user exists
    const user = await User.findOne({ email });
    if (!user) return res.status(400).json({ message: 'User not found' });

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

    // Generate JWT token
    const token = jwt.sign({ _id: user._id }, 'JWT_SECRET');
    res.header('auth-token', token).json({ token });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Server error' });
  }
});

Step 4: Creating React Frontend

Now that we have implemented the backend logic for our authentication system, let’s create a React frontend to interact with our backend APIs.

Create a new React project using create-react-app:

npx create-react-app frontend
cd frontend

Next, let’s install a few dependencies for our frontend project. We will be using axios to make HTTP requests to our backend:

npm install axios

Now, let’s create a new folder called components in our frontend project and create Login.js and Signup.js files inside it. These files will contain our login and signup forms.

In Signup.js, let’s create a simple signup form:

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

const Signup = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSignup = async () => {
    try {
      const response = await axios.post('http://localhost:5000/api/auth/signup', { email, password });
      console.log(response.data);
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <div>
      <h2>Signup</h2>
      <input type="email" placeholder="Email" onChange={(e) => setEmail(e.target.value)} />
      <input type="password" placeholder="Password" onChange={(e) => setPassword(e.target.value)} />
      <button onClick={handleSignup}>Signup</button>
    </div>
  );
};

export default Signup;

Similarly, in Login.js, let’s create a simple login form:

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

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleLogin = async () => {
    try {
      const response = await axios.post('http://localhost:5000/api/auth/login', { email, password });
      console.log(response.data);
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <div>
      <h2>Login</h2>
      <input type="email" placeholder="Email" onChange={(e) => setEmail(e.target.value)} />
      <input type="password" placeholder="Password" onChange={(e) => setPassword(e.target.value)} />
      <button onClick={handleLogin}>Login</button>
    </div>
  );
};

export default Login;

Step 5: Integrating Frontend with Backend

Now that we have our frontend components, let’s integrate them into our main App.js file in the frontend folder:

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Login from './components/Login';
import Signup from './components/Signup';

const App = () => {
  return (
    <Router>
      <div>
        <Switch>
          <Route path="/login" component={Login} />
          <Route path="/signup" component={Signup} />
        </Switch>
      </div>
    </Router>
  );
};

export default App;

Now, you can start both the backend and frontend servers by running npm start in the respective folders. You should now be able to signup and login using your MERN stack authentication system.

This tutorial covers the basic setup for implementing user authentication using the MERN stack. Remember to handle user authentication securely in production applications and consider adding features like email verification and password reset functionality for a more complete user experience.

0 0 votes
Article Rating
4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@sourabhrawat1
4 months ago

Please upload backend part of authentication 😊

@sandeshrajurkar6332
4 months ago

can you please create video on connecting database to this login form

@printmusic5m50
4 months ago

Where is Source code

@printmusic5m50
4 months ago

Wow nice❤