Skip to main content
🔐Security

Authentication vs Authorization: Understanding the Two Pillars of Security

Security in modern systems relies on two fundamental concepts: authentication and authorization. While often used interchangeably, they serve entirely diff...

📖 8 min read

Authentication vs Authorization: Understanding the Two Pillars of Security

Security in modern systems relies on two fundamental concepts: authentication and authorization. While often used interchangeably, they serve entirely different purposes. Authentication answers "Who are you?" while authorization answers "What can you do?". Understanding this distinction is critical for building secure applications and acing system design interviews.

What is Authentication?

Authentication is the process of verifying a user's identity. It confirms that someone is who they claim to be before granting any access. Think of it as showing your passport at airport security — you're proving your identity.

Common Authentication Methods

Method How It Works Security Level Use Case
Password-Based User provides username + password Low-Medium Most web applications
Multi-Factor (MFA) Combines 2+ factors: something you know, have, or are High Banking, enterprise apps
Biometric Fingerprint, face scan, iris recognition High Mobile devices, physical access
SSO (Single Sign-On) One login grants access to multiple services Medium-High Enterprise ecosystems (Google Workspace)
Certificate-Based Digital certificates verify identity via PKI Very High Service-to-service, mTLS
Token-Based JWT or opaque tokens after initial login Medium-High APIs, SPAs, mobile apps

Password-Based Authentication with Hashing

Never store passwords in plain text. Always use a slow hashing algorithm like bcrypt or Argon2. Here is how password hashing works in Node.js:

const bcrypt = require('bcrypt');
const SALT_ROUNDS = 12;

// Registration: Hash the password before storing
async function registerUser(email, password) {
  const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS);
  await db.users.insert({ email, password: hashedPassword });
}

// Login: Compare provided password with stored hash
async function loginUser(email, password) {
  const user = await db.users.findByEmail(email);
  if (!user) throw new Error('User not found');

  const isValid = await bcrypt.compare(password, user.password);
  if (!isValid) throw new Error('Invalid credentials');

  return generateToken(user); // Issue JWT or session
}

Use our Security and Crypto Tools to experiment with hashing algorithms and see how different inputs produce different hash outputs.

Multi-Factor Authentication (MFA)

MFA combines two or more independent authentication factors:

  • Something you know — password, PIN, security question
  • Something you have — phone (TOTP app), hardware key (YubiKey), smart card
  • Something you are — fingerprint, face recognition, voice pattern
const speakeasy = require('speakeasy');

// Generate TOTP secret during MFA enrollment
function generateMfaSecret(userId) {
  const secret = speakeasy.generateSecret({
    name: `MyApp:${userId}`,
    issuer: 'MyApp'
  });
  // Store secret.base32 in database
  return { secret: secret.base32, qrUrl: secret.otpauth_url };
}

// Verify TOTP code during login
function verifyMfaCode(storedSecret, userCode) {
  return speakeasy.totp.verify({
    secret: storedSecret,
    encoding: 'base32',
    token: userCode,
    window: 1 // Allow 30-second clock drift
  });
}

What is Authorization?

Authorization determines what an authenticated user is allowed to do. After proving identity, the system checks permissions to decide if the requested action is permitted. This is like having a boarding pass after showing your passport — it determines which flight and seat you can access.

Authorization Models

Role-Based Access Control (RBAC)

RBAC assigns permissions to roles, and roles are assigned to users. It is the most common authorization model in enterprise applications.

Role Permissions Example Users
Admin Create, Read, Update, Delete, Manage Users System administrators
Editor Create, Read, Update Content managers
Viewer Read only Regular users
// RBAC middleware in Express.js
function authorize(...allowedRoles) {
  return (req, res, next) => {
    const userRole = req.user.role; // Set during authentication
    if (!allowedRoles.includes(userRole)) {
      return res.status(403).json({ error: 'Insufficient permissions' });
    }
    next();
  };
}

// Usage in routes
app.get('/api/users', authenticate, authorize('admin'), getUsers);
app.get('/api/posts', authenticate, authorize('admin', 'editor', 'viewer'), getPosts);
app.post('/api/posts', authenticate, authorize('admin', 'editor'), createPost);
app.delete('/api/posts/:id', authenticate, authorize('admin'), deletePost);

Attribute-Based Access Control (ABAC)

ABAC makes authorization decisions based on attributes of the user, resource, action, and environment. It is more flexible than RBAC but more complex to implement.

// ABAC policy evaluation
function evaluatePolicy(subject, resource, action, environment) {
  const policies = [
    {
      name: 'Doctors can view patient records in their department',
      condition: (s, r, a, e) =>
        s.role === 'doctor' &&
        r.type === 'patient_record' &&
        a === 'read' &&
        s.department === r.department
    },
    {
      name: 'Only during business hours for non-emergency',
      condition: (s, r, a, e) =>
        r.priority === 'emergency' ||
        (e.hour >= 8 && e.hour <= 18)
    }
  ];

  return policies.every(p => p.condition(subject, resource, action, environment));
}

RBAC vs ABAC Comparison

Feature RBAC ABAC
Complexity Simple to implement Complex, requires policy engine
Granularity Role-level (coarse) Attribute-level (fine-grained)
Scalability Role explosion with many permissions Scales well with dynamic policies
Context-Aware No (static roles) Yes (time, location, device)
Best For Standard enterprise apps Healthcare, finance, government

Key Differences: Authentication vs Authorization

Aspect Authentication Authorization
Purpose Verifies identity Verifies permissions
Question Who are you? What can you do?
Order Always comes first Happens after authentication
HTTP Status 401 Unauthorized 403 Forbidden
Mechanism Passwords, tokens, biometrics Roles, policies, ACLs
Visibility User sees login process Invisible to user (backend)
Changeable User can change credentials Admin controls permissions

OAuth 2.0 Roles in Authentication and Authorization

OAuth 2.0 elegantly separates authentication and authorization concerns across four distinct roles:

  • Resource Owner — The user who owns the data (authenticates and grants permission)
  • Client — The application requesting access (needs authorization)
  • Authorization Server — Issues tokens after authentication (handles both authn and authz)
  • Resource Server — Hosts protected data (validates authorization tokens)

When combined with JSON Web Tokens (JWT), OAuth 2.0 can encode both identity (authentication) and permissions (authorization) in a single token.

Real-World Examples

Banking Application

Authentication: Customer logs in with username, password, and MFA code from their phone. The bank verifies their identity against stored credentials.

Authorization: After login, the customer can view their own accounts and transfer money. They cannot view other customers' accounts or modify interest rates — those require different authorization levels.

Healthcare System

Authentication: A doctor scans their badge and enters a PIN at a workstation. The system confirms they are Dr. Smith from the cardiology department.

Authorization: Dr. Smith can view cardiac patient records in their department (ABAC policy) but cannot access records from psychiatry. A nurse on the same floor might have read-only access to vitals but cannot modify treatment plans.

E-Commerce Platform

Authentication: A customer signs in with Google SSO. The platform verifies their Google identity token and creates or links an account.

Authorization: The customer can browse products, place orders, and review their order history. They cannot access the admin dashboard, modify product listings, or view other customers' orders. A seller on the same platform has authorization to manage their own product listings but not others'.

Implementation Best Practices

  • Always authenticate before authorizing — Never skip authentication checks. Return 401 for unauthenticated requests and 403 for unauthorized ones.
  • Use established protocols — Leverage OAuth 2.0 and OpenID Connect rather than building custom authentication flows.
  • Implement defense in depth — Apply authorization checks at multiple layers: API gateway, application middleware, and database level.
  • Follow the principle of least privilege — Grant the minimum permissions necessary. Start restrictive and add permissions as needed, as discussed in Zero Trust Architecture.
  • Audit everything — Log all authentication attempts and authorization decisions for security monitoring and compliance.
  • Protect against common attacks — Implement rate limiting on login endpoints to prevent brute force attacks.

Test your understanding of authentication headers and token formats with our API and Network Tools.

Common Mistakes to Avoid

  • Mixing up 401 and 403 — 401 means "not authenticated," 403 means "authenticated but not authorized"
  • Client-side authorization only — Always enforce authorization on the server. Client-side checks are only for UX.
  • Hardcoding roles — Use a policy engine or database-driven roles rather than hardcoded checks scattered throughout code.
  • No session invalidation — Ensure you can revoke access tokens and sessions when a user's permissions change or they are deactivated.
  • Storing plain-text passwords — Always hash passwords with bcrypt, scrypt, or Argon2. See our Encryption guide for more on hashing.

Frequently Asked Questions

Can you have authorization without authentication?

Technically, no. Authorization depends on knowing who the user is. However, some systems provide limited access to anonymous users (like viewing public pages), which could be considered a form of default authorization without explicit authentication. In any secure system, meaningful authorization always requires authentication first.

What is the difference between OAuth and OpenID Connect?

OAuth 2.0 is an authorization framework — it grants access to resources. OpenID Connect (OIDC) is an authentication layer built on top of OAuth 2.0 — it verifies identity. When you "Sign in with Google," OIDC handles authentication while OAuth 2.0 handles authorization to access your Google data.

Should I use RBAC or ABAC for my application?

Start with RBAC if your permission model is straightforward (admin, editor, viewer). Move to ABAC when you need context-dependent decisions: access based on time of day, geographic location, resource ownership, or department membership. Many systems use a hybrid approach with RBAC as the foundation and ABAC for specific fine-grained policies.

How do JWTs relate to authentication and authorization?

JWTs serve both purposes. The token itself proves authentication (it was issued after successful login). The claims inside the token (roles, permissions, scopes) drive authorization decisions. This makes JWTs efficient because the server can make authorization decisions without a database lookup on every request.

What is the best way to handle authorization in microservices?

In a microservices architecture, use an API gateway for authentication and coarse-grained authorization. Each service then handles fine-grained authorization locally. Pass user context (roles, claims) via JWT tokens between services. Consider a centralized policy engine like Open Policy Agent (OPA) for consistent authorization across services. Explore more in our tools section.

Related Articles