🔐 Authentication and Authorization

Security is fundamental to API design. Before we implement authentication in our Express API, we need to understand three critical concepts that are often confused: Identification, Authentication, and Authorization. Each serves a different purpose in securing your application.


The Security Trinity

<aside> 🔑

The Three Pillars of API Security:

Identification → "Who claims to be accessing?"

Authentication → "Can you prove who you are?"

Authorization → "Are you allowed to do this?"

</aside>


1. Identification: "Who Are You?"

Identification is simply the claim of identity - providing a username, email, or user ID.

Real-World Analogy

When you walk up to a hotel front desk and say "I'm John Smith," that's identification. You're claiming to be John Smith, but you haven't proven it yet.

In Express APIs

// User provides identification
POST /api/auth/login
{
  "email": "[[email protected]](<mailto:[email protected]>)",  // ⬅ This is identification
  "password": "secretpassword"
}

// Or via URL parameter
GET /api/users/john-smith  // Username as identification

// Or via JWT token payload
{
  "id": "user-123",       // ⬅ User identification
  "email": "[[email protected]](<mailto:[email protected]>)",
  "username": "johnsmith"
}

<aside> ⚠️

Important: Identification alone is not secure. Anyone can claim to be anyone. It's just the starting point.

</aside>


2. Authentication: "Prove It"

Authentication is the process of verifying that the claimed identity is legitimate.

Real-World Analogy

When you show your driver's license or passport at the hotel, that's authentication. You're proving you are who you claim to be.

Common Authentication Methods

Password-Based

// User proves identity with password
const isAuthenticated = await [bcrypt.compare](<http://bcrypt.compare>)(
  providedPassword,
  storedHashedPassword
)

if (isAuthenticated) {
  // Generate session token
  const token = jwt.sign({ userId: [user.id](<http://user.id>) })
}

Token-Based

// User proves identity with JWT
const authenticateToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1]
  
  try {
    const decoded = jwt.verify(token, SECRET)
    req.user = decoded
    next()
  } catch {
    res.status(401).json({ error: 'Invalid token' })
  }
}