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.
Please upload backend part of authentication 😊
can you please create video on connecting database to this login form
Where is Source code
Wow nice❤