In security systems, authentication verifies identity ("Who are you?"), while authorization determines permissions ("What can you do?"). These complementary mechanisms form the foundation of access control.
Common authentication methods include:
// Basic username/password authentication in Node.js
const authenticateUser = async (username, password) => {
const user = await User.findOne({ username });
if (!user) throw new Error('User not found');
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) throw new Error('Invalid credentials');
return user; // Authentication successful
};
Authorization typically involves:
// Role-based authorization middleware in Express.js
const authorizeAdmin = (req, res, next) => {
if (req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
// Usage in route
app.get('/admin-dashboard', authenticateUser, authorizeAdmin, (req, res) => {
// Admin-only content
});
Here's how JWT combines both concepts:
// JWT authentication and authorization flow
const jwt = require('jsonwebtoken');
// Authentication: Generate token
const token = jwt.sign(
{ userId: user.id, role: user.role }, // Payload
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
// Authorization: Verify token and check permissions
const verifyToken = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).send('Unauthorized');
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded; // Attach user data to request
next();
} catch (err) {
return res.status(403).send('Invalid token');
}
};
Best practices include:
- Always use HTTPS for authentication
- Implement proper session management
- Follow principle of least privilege in authorization
- Regularly audit permissions
Avoid these mistakes:
// BAD: Hardcoding credentials
if (username === "admin" && password === "password123") {
// Vulnerable to brute force attacks
}
// BAD: Frontend authorization only
// Client-side checks can be bypassed
if (user.role === 'admin') {
showAdminPanel(); // MUST verify server-side
}
In security systems, authentication and authorization are two fundamental processes that work together but serve distinct purposes:
- Authentication verifies who you are (identity validation)
- Authorization determines what you can do (permission levels)
Authentication typically involves credentials like:
// Basic authentication example in Node.js
const validateUser = (username, password) => {
const user = db.users.find(u => u.username === username);
if (!user) return false;
return bcrypt.compareSync(password, user.passwordHash);
};
Authorization comes after successful authentication. Common patterns include:
// Role-based authorization middleware
const authorize = (requiredRole) => {
return (req, res, next) => {
if (req.user.role !== requiredRole) {
return res.status(403).send('Forbidden');
}
next();
};
};
Here's how they work together in a web application:
// Express.js route with both authentication and authorization
app.post('/admin/dashboard',
authenticateUser, // Authentication middleware
authorize('admin'), // Authorization middleware
(req, res) => {
// Admin dashboard logic
}
);
- OAuth 2.0: Handles both authentication and authorization
- JWT: Often contains both identity and permission claims
- SAML: Primarily for authentication with authorization extensions
- Always authenticate before authorizing
- Implement principle of least privilege
- Use established libraries instead of custom solutions
- Regularly audit permission assignments