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

? Backend

The document outlines the signup and login functionality of a Task Management System, detailing both frontend and backend processes. It describes how user data is handled, including validation, token generation, and error management, using technologies like React, Axios, Express, and MongoDB. Additionally, it explains the relationship between components and the flow of data during user registration and login, emphasizing security measures such as password hashing and token protection.

Uploaded by

Ubaid Altaf
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)
8 views11 pages

? Backend

The document outlines the signup and login functionality of a Task Management System, detailing both frontend and backend processes. It describes how user data is handled, including validation, token generation, and error management, using technologies like React, Axios, Express, and MongoDB. Additionally, it explains the relationship between components and the flow of data during user registration and login, emphasizing security measures such as password hashing and token protection.

Uploaded by

Ubaid Altaf
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

🔹 BACKEND: authController.

js

✅ Signup (Register) Controller

js

CopyEdit

export const signup = async (req, res) => {

const { name, email, password, terms } = req.body;

 🔍 Extracts data from the request body sent from frontend: name, email, password, and
optionally terms.

js

CopyEdit

try {

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

 ✅ Checks if a user with the given email already exists in MongoDB using User.findOne().

js

CopyEdit

if (existingUser) {

return res.status(409).json({

success: false,

error: 'Email already in use'

});

 ❌ If email is found, it returns HTTP status 409 Conflict with a message.

js

CopyEdit

const user = await User.create({ name, email, password });

 ✅ If not found, it creates a new user using the User model. Password is hashed (inside User
model logic, usually via pre-save).

js

CopyEdit
res.status(201).json({

success: true,

token: generateToken(user._id),

user: {

_id: user._id,

name: user.name,

email: user.email,

isAdmin: user.isAdmin

});

 🔐 Returns HTTP 201 Created response with:

o a JWT token (generated from user ID)

o user data (but not password)

js

CopyEdit

} catch (err) {

console.error(err);

res.status(500).json({

success: false,

error: 'Server error'

});

};

 🛑 Catches any errors and returns 500 Internal Server Error.

✅ Login Controller

js

CopyEdit

export const login = async (req, res) => {


const { email, password } = req.body;

 📥 Extracts email and password from request body.

js

CopyEdit

const user = await User.findOne({ email }).select('+password');

 🔍 Finds user by email and includes password field (which is usually excluded in the schema for
security).

js

CopyEdit

if (!user || !(await user.matchPassword(password))) {

 ❌ If user is not found, or if the password doesn’t match (using method from schema), return 401
Unauthorized.

js

CopyEdit

return res.status(401).json({

success: false,

error: 'Invalid email or password'

});

 🧠 Valid login goes here:

js

CopyEdit

res.status(200).json({

success: true,

token: generateToken(user._id),

user: {

_id: user._id,

name: user.name,

email: user.email,

isAdmin: user.isAdmin
}

});

 🔐 Sends 200 OK with JWT token and user details.

🔹 FRONTEND: Register.js

js

CopyEdit

const [formData, setFormData] = useState({

name: '',

email: '',

password: '',

});

 🎯 Tracks form values using state. Updated by user input.

js

CopyEdit

const handleChange = (e) => {

setFormData({ ...formData, [e.target.name]: e.target.value });

};

 📝 Handles text input changes and updates state accordingly.

js

CopyEdit

const handleSubmit = async (e) => {

e.preventDefault();

 🚫 Prevents page from refreshing on form submit.

js

CopyEdit

try {

await registerUser(formData);

alert('Registration successful!');
navigate('/login');

 ✅ Calls the registerUser service, which makes a POST request to backend. Then redirects to login
page.

js

CopyEdit

} catch (err) {

console.error(err);

alert(err.response?.data?.message || 'Registration failed');

};

 ⚠️Catches any errors and shows message.

🔹 FRONTEND: auth.js service file

js

CopyEdit

import api from './api';

 📦 Uses pre-configured Axios instance (base URL is http://localhost:5000/api).

js

CopyEdit

export const registerUser = async (userData) => {

const res = await api.post('/auth/register', userData);

return res.data;

};

 🔁 Makes POST request to /auth/register and sends user data.

js

CopyEdit

export const loginUser = async (userData) => {

const res = await api.post('/auth/login', userData);

return res.data;
};

 🔁 Login request to /auth/login.

🔐 ProtectedRoute.js

js

CopyEdit

const token = localStorage.getItem('token');

if (!token) return <Navigate to="/login" />;

 🚫 If no token is found, redirect to login.

🔹 RELATION BETWEEN COMPONENTS

Part Connected To

Register form ➡️registerUser() in auth.js

registerUser ➡️POST /api/auth/register ➡️signup controller

Login form ➡️loginUser() in auth.js

loginUser ➡️POST /api/auth/login ➡️login controller

After login ➡️Save token in localStorage

ProtectedRoute ➡️Reads token and shows protected Dashboard

✅ SUMMARY

 🔄 Frontend sends POST to backend using Axios.

 🔐 Backend handles validation, token generation, and sends a response.

 🛡️ProtectedRoute ensures only logged-in users see certain pages.

 🧠 MongoDB stores user securely with hashed passwords.

Let me know when you're ready — next, we can go through the task creation, update, delete, toggle
features step-by-step too.
Tools

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Great! Let's now dive deep into the full flow of signup (registration) and login functionality in
your Task Management System — covering both frontend and backend logic, step by step, with
highlighted code and in-depth explanation of how everything connects and works together.

✅ PART 1: SIGNUP / REGISTRATION FLOW

🧠 OVERVIEW:
 Frontend sends a POST request with name, email, password to /api/auth/register
 Backend receives and validates data, creates a new user, hashes password, saves it to
MongoDB
 JWT Token is generated and sent back
 Frontend shows success and navigates user to /login

🔹 FRONTEND CODE: Register.js


const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
});

🧠 This creates a state object to hold the values from the form inputs (controlled inputs).
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};

🧠 This function dynamically updates the formData state whenever the user types in an input.

 e.target.name matches one of the keys in formData


 It spreads the previous state and updates the one that changed.

const handleSubmit = async (e) => {


e.preventDefault();
try {
await registerUser(formData);
alert('Registration successful!');
navigate('/login');
} catch (err) {
alert(err.response?.data?.message || 'Registration failed');
}
};

🧠 When form is submitted:

 registerUser(formData) sends a POST request to backend


 If it succeeds: shows success alert and navigates to login
 If it fails: shows error from backend

// services/auth.js
export const registerUser = async (userData) => {
const res = await api.post('/auth/register', userData);
return res.data;
};

🧠 api is an Axios instance with base URL: http://localhost:5000/api

🔹 BACKEND CODE: authRoutes.js


router.post('/register', signup);

🧠 Defines the API endpoint /api/auth/register which is handled by the signup function.

🔹 CONTROLLER: authController.js
export const signup = async (req, res) => {
const { name, email, password } = req.body;
🧠 Reads name, email, password from request body.

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


if (existingUser) {
return res.status(409).json({
success: false,
error: 'Email already in use'
});
}

🧠 Checks if email is already registered. If yes, sends 409 Conflict.

const user = await User.create({ name, email, password });

🧠 Creates new user and stores in MongoDB.

❗ Your Mongoose schema should hash the password before saving (using pre-save hook with
bcrypt).

res.status(201).json({
success: true,
token: generateToken(user._id),
user: {
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin
}
});

🧠 On success:

 Responds with 201 Created


 Includes a JWT token and user info (except password)

🔐 generateToken.js
import jwt from 'jsonwebtoken';

const generateToken = (id) => {


return jwt.sign({ id }, process.env.JWT_SECRET, {
expiresIn: '30d',
});
};

export default generateToken;


🧠 Takes user ID, signs it using a secret key, and returns a token valid for 30 days.

🧱 DATABASE MODEL: User.js


userSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
});

🧠 Automatically hashes the password before saving the user.

✅ PART 2: LOGIN FLOW

🧠 OVERVIEW:
 User enters email + password
 Frontend sends POST request to /api/auth/login
 Backend checks if user exists and password is valid
 Returns JWT token if correct

🔹 FRONTEND Login.js
const res = await loginUser(formData);
localStorage.setItem('token', res.token);
navigate('/dashboard');

🧠 On successful login, token is saved in localStorage and user is redirected to protected


/dashboard.

🔹 BACKEND authController.js
const user = await User.findOne({ email }).select('+password');
if (!user || !(await user.matchPassword(password))) {
return res.status(401).json({ error: 'Invalid email or password' });
}

🧠 Looks up user by email, ensures password matches using:


userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};

res.status(200).json({
success: true,
token: generateToken(user._id),
user: { ... }
});

🧠 Sends token back to frontend to be stored.

🔐 PROTECTED ROUTES (Frontend)


const token = localStorage.getItem('token');
if (!token) return <Navigate to="/login" replace />;

🧠 If user tries to visit /dashboard without login, they are redirected.

🔄 RELATIONSHIP FLOW
Form (React) → API Request (Axios) → Express Route → Controller → MongoDB
⬑ JWT Token returned ⬐

✅ You can now:

 Check MongoDB using MongoDB Compass or CLI


 See registered users and verify hashed passwords
 Use Bearer token in headers for protected APIs

Would you like me to now explain:

 How ProtectedRoute works in more depth?


 How to check if a user is logged in?
 How to logout / destroy token?
 Or continue to task creation module?

Let me know and I’ll guide you step by step.

You might also like