Input Validation And Authentication Flow
In modern applications (web, mobile, or desktop), Input Validation and Authentication Flow are two fundamental security concepts. If you understand these properly, you understand the foundation of secure software.
What Is Input Validation?
Definition
Input Validation is the process of checking whether the data a user provides is correct, safe, and in the expected format before your system uses it.
Whenever a user enters:
That is input.
If you do not validate input, attackers can:
Why Input Validation Is Important
Imagine someone enters this into a login field:
' OR 1=1 --
If your system blindly trusts that input, it might:
Validation protects your system from:
Types Of Input Validation
1. Client-Side Validation
This happens in the browser (using JavaScript).
Purpose:
Example:
Important: Client-side validation is NOT secure by itself. Attackers can bypass it.
2. Server-Side Validation
This happens on the backend (server).
Purpose:
Server-side validation is mandatory.
Basic Input Validation Example (Node.js + Express)
Here is a simple example of validating a login request.
const express = require('express');
const app = express();
app.use(express.json());
app.post('/login', (req, res) => {
const { email, password } = req.body;
// Check if fields exist
if (!email || !password) {
return res.status(400).json({ message: "Email and password are required." });
}
// Check email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
return res.status(400).json({ message: "Invalid email format." });
}
// Check password length
if (password.length < 8) {
return res.status(400).json({ message: "Password must be at least 8 characters." });
}
res.json({ message: "Input validated successfully." });
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
This example checks:
But validation alone does not log users in. That is where Authentication Flow comes in.
What Is Authentication?
Definition
Authentication is the process of verifying who a user is.
It answers this question:
"Are you really who you claim to be?"
Common authentication methods:
Authentication Flow Explained Step-By-Step
Let us walk through a typical login process.
Step 1: User Sends Login Request
User enters:
The browser sends data to the server.
Step 2: Input Validation
The server checks:
If validation fails → reject request.
Step 3: Find User In Database
Server searches database for the email.
If user does not exist → return error.
Step 4: Compare Passwords Securely
Important: Passwords should NEVER be stored in plain text.
Instead:
When user logs in:
If hashes match → authentication successful.
Step 5: Generate Authentication Token
If login is successful:
Full Authentication Flow Example (Node.js + Express + JWT)
Below is a simplified example.
You will need:
Install:
npm install express bcrypt jsonwebtoken
Now the code:
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const SECRET_KEY = "mysecretkey";
// Fake database
let users = [];
// Register route
app.post('/register', async (req, res) => {
const { email, password } = req.body;
// Input validation
if (!email || !password) {
return res.status(400).json({ message: "Email and password required." });
}
if (password.length < 8) {
return res.status(400).json({ message: "Password must be at least 8 characters." });
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Save user
users.push({ email, password: hashedPassword });
res.json({ message: "User registered successfully." });
});
// Login route
app.post('/login', async (req, res) => {
const { email, password } = req.body;
// Validate input
if (!email || !password) {
return res.status(400).json({ message: "Email and password required." });
}
// Find user
const user = users.find(u => u.email === email);
if (!user) {
return res.status(400).json({ message: "Invalid credentials." });
}
// Compare password
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ message: "Invalid credentials." });
}
// Generate token
const token = jwt.sign({ email: user.email }, SECRET_KEY, { expiresIn: "1h" });
res.json({ message: "Login successful.", token });
});
// Protected route example
app.get('/dashboard', (req, res) => {
const authHeader = req.headers['authorization'];
if (!authHeader) {
return res.status(401).json({ message: "Access denied. No token provided." });
}
const token = authHeader.split(" ")[1];
try {
const verified = jwt.verify(token, SECRET_KEY);
res.json({ message: "Welcome to dashboard.", user: verified });
} catch (err) {
res.status(400).json({ message: "Invalid token." });
}
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
How Input Validation And Authentication Work Together
Here is the relationship:
Without validation:
Without authentication:
They are separate but tightly connected security layers.
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const SECRET_KEY = "mysecretkey";
// Fake database
let users = [];
// Register route
app.post('/register', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: "Email and password required." });
}
if (password.length < 8) {
return res.status(400).json({ message: "Password must be at least 8 characters." });
}
const hashedPassword = await bcrypt.hash(password, 10);
users.push({ email, password: hashedPassword });
res.json({ message: "User registered successfully." });
});
// Login route
app.post('/login', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: "Email and password required." });
}
const user = users.find(u => u.email === email);
if (!user) {
return res.status(400).json({ message: "Invalid credentials." });
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ message: "Invalid credentials." });
}
const token = jwt.sign({ email: user.email }, SECRET_KEY, { expiresIn: "1h" });
res.json({ message: "Login successful.", token });
});
// Protected route
app.get('/dashboard', (req, res) => {
const authHeader = req.headers['authorization'];
if (!authHeader) {
return res.status(401).json({ message: "Access denied. No token provided." });
}
const token = authHeader.split(" ")[1];
try {
const verified = jwt.verify(token, SECRET_KEY);
res.json({ message: "Welcome to dashboard.", user: verified });
} catch (err) {
res.status(400).json({ message: "Invalid token." });
}
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});