0% found this document useful (0 votes)
10 views11 pages

Chat App

This document outlines the implementation of a simple chat application using Node.js, Express, MongoDB, and Socket.io for real-time communication. Key features include user registration and login with JWT authentication, real-time messaging, and middleware for security and rate limiting. The document provides a step-by-step guide for setting up the project, including environment configuration, server setup, user model creation, authentication routes, and frontend integration.

Uploaded by

Alvin Kono
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views11 pages

Chat App

This document outlines the implementation of a simple chat application using Node.js, Express, MongoDB, and Socket.io for real-time communication. Key features include user registration and login with JWT authentication, real-time messaging, and middleware for security and rate limiting. The document provides a step-by-step guide for setting up the project, including environment configuration, server setup, user model creation, authentication routes, and frontend integration.

Uploaded by

Alvin Kono
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

Sure!

Here's a simple backend application that integrates all the concepts


we've discussed: Node.js, Express, MongoDB, and Socket.io for real-time
communication. The project will simulate a chat application where users
can send and receive messages in real-time.

Project Overview

1. User Registration and Login (JWT authentication).

2. Real-time chat using WebSockets (Socket.io).

3. MongoDB to store user data and messages.

4. Middleware for authentication.

5. Rate-limiting to avoid abuse.

6. Environment variables for secure configurations.

Step-by-Step Implementation

Step 1: Initialize the Project


Start by setting up your project.

mkdir chat-app

cd chat-app

npm init -y

npm install express mongoose socket.io jsonwebtoken bcryptjs express-


validator dotenv express-rate-limit helmet

express: Web framework for Node.js.

mongoose: MongoDB ODM.

socket.io: WebSocket for real-time communication.

jsonwebtoken: JWT for authentication.

bcryptjs: Password hashing.

express-validator: Input validation.

dotenv: For managing environment variables.

express-rate-limit: Rate limiting middleware.

helmet: Security middleware to protect HTTP headers.

Step 2: Set Up Environment Variables


Create a .env file to store sensitive information like database URL and JWT
secret.

MONGO_URI=mongodb://localhost:27017/chat-app

JWT_SECRET=your_jwt_secret

PORT=5000

Step 3: Set Up Basic Express Server

In server.js, create a basic Express server.

const express = require('express');

const mongoose = require('mongoose');

const dotenv = require('dotenv');

const helmet = require('helmet');

const rateLimit = require('express-rate-limit');

const cors = require('cors');

dotenv.config();

const app = express();

const port = process.env.PORT || 5000;

// Middleware

app.use(express.json());

app.use(helmet());

app.use(cors());

// Rate limiting (100 requests per 15 minutes)


const limiter = rateLimit({

windowMs: 15 * 60 * 1000,

max: 100,

message: 'Too many requests, please try again later.'

});

app.use(limiter);

// Connect to MongoDB

mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true,


useUnifiedTopology: true })

.then(() => console.log('Connected to MongoDB'))

.catch(err => console.log('MongoDB connection error:', err));

app.listen(port, () => {

console.log(`Server running on port ${port}`);

});

Step 4: Create the User Model

Create a models/User.js file to define the MongoDB schema for users.

const mongoose = require('mongoose');

const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({

username: { type: String, required: true, unique: true },

email: { type: String, required: true, unique: true },

password: { type: String, required: true }

});
// Hash password before saving the user

userSchema.pre('save', async function(next) {

if (!this.isModified('password')) return next();

this.password = await bcrypt.hash(this.password, 10);

next();

});

// Check if password is correct

userSchema.methods.isPasswordValid = async function(password) {

return bcrypt.compare(password, this.password);

};

module.exports = mongoose.model('User', userSchema);

Step 5: Set Up Authentication Routes

Create routes for registering and login users in routes/auth.js.

const express = require('express');

const bcrypt = require('bcryptjs');

const jwt = require('jsonwebtoken');

const User = require('../models/User');

const { check, validationResult } = require('express-validator');

const router = express.Router();

// Register User

router.post('/register', [
check('username').notEmpty().withMessage('Username is required'),

check('email').isEmail().withMessage('Valid email is required'),

check('password').isLength({ min: 6 }).withMessage('Password must be


at least 6 characters')

], async (req, res) => {

const errors = validationResult(req);

if (!errors.isEmpty()) return res.status(400).json({ errors:


errors.array() });

const { username, email, password } = req.body;

try {

// Check if user exists

const userExists = await User.findOne({ email });

if (userExists) return res.status(400).json({ message: 'User already


exists' });

const user = new User({ username, email, password });

await user.save();

// Create JWT token

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET,


{ expiresIn: '1h' });

res.json({ token });

} catch (err) {

console.log(err);

res.status(500).json({ message: 'Server error' });

});
// Login User

router.post('/login', [

check('email').isEmail().withMessage('Valid email is required'),

check('password').notEmpty().withMessage('Password is required')

], async (req, res) => {

const errors = validationResult(req);

if (!errors.isEmpty()) return res.status(400).json({ errors:


errors.array() });

const { email, password } = req.body;

try {

const user = await User.findOne({ email });

if (!user) return res.status(400).json({ message: 'Invalid credentials' });

const isPasswordValid = await user.isPasswordValid(password);

if (!isPasswordValid) return res.status(400).json({ message: 'Invalid


credentials' });

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET,


{ expiresIn: '1h' });

res.json({ token });

} catch (err) {

console.log(err);

res.status(500).json({ message: 'Server error' });

});

module.exports = router;
Step 6: Set Up Chat Functionality with Socket.io

In server.js, integrate Socket.io to handle real-time messaging.

const http = require('http');

const socketIo = require('socket.io');

// Create HTTP server to use with Socket.io

const server = http.createServer(app);

const io = socketIo(server);

// Handle new connection

io.on('connection', (socket) => {

console.log('A user connected');

// Listen for chat messages

socket.on('chatMessage', (msg) => {

io.emit('chatMessage', msg); // Broadcast message to all connected


clients

});

socket.on('disconnect', () => {

console.log('A user disconnected');

});

});

// Start server

server.listen(port, () => {

console.log(`Server running on port ${port}`);


});

Step 7: Frontend for Chat (HTML & JS)

You can create a simple HTML page to interact with the backend. Here’s a
minimal frontend using Socket.io-client:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-


scale=1.0">

<title>Chat App</title>

<script src="/socket.io/socket.io.js"></script>

</head>

<body>

<h1>Chat App</h1>

<input id="message" type="text" placeholder="Type a message" />

<button onclick="sendMessage()">Send</button>

<ul id="messages"></ul>

<script>

const socket = io();

// Listen for incoming chat messages

socket.on('chatMessage', (msg) => {

const li = document.createElement('li');

li.textContent = msg;

document.getElementById('messages').appendChild(li);
});

// Send a message to the server

function sendMessage() {

const message = document.getElementById('message').value;

socket.emit('chatMessage', message);

document.getElementById('message').value = ''; // Clear input

</script>

</body>

</html>

Step 8: Testing and Running the App

1. Run MongoDB (ensure it's running locally or in the cloud).

2. Start the server:

node server.js

3. Open the HTML file in the browser and use multiple tabs to simulate
different users.
---

Conclusion

In this project, we've built a simple chat application with the following:

User authentication with JWT.

Real-time messaging using Socket.io.

MongoDB for storing user data and messages.

Express.js for the backend API.

Rate limiting and security headers using express-rate-limit and helmet.

This project gives you a comprehensive view of a production-grade


backend application. You can extend it by adding features like:

Persisting chat messages in MongoDB.

Adding more advanced user features like roles or profiles.

Using Redis for more complex message handling and scaling.

Let me know if you need further clarification or more advanced features!

You might also like