---
title: "Authentication vs. Authorization vs. OAuth: The 'ID Card' Mental Model"
description: "Stop mixing up 401 and 403. A mastery guide to AuthN (Who you are), AuthZ (What you can do), and the OAuth Valet Key."
pubDate: "2023-05-21"
lang: "en"
slug: "authentication-vs-authorization-vs-oauth"
url: "https://hoangyell.com/authentication-vs-authorization-vs-oauth/"
author: "HoangYell"
translation_vi: "https://hoangyell.com/vi/authentication-vs-authorization-vs-oauth/"
categories: ["System Design"]
tags: ["system-design", "security", "api"]
heroImage: "https://raw.githubusercontent.com/HoangGeek/store/main/webp/photo-1614064641938-3bbee52942c7.webp"
---

The two most confused words in software engineering start with "Auth".

If you ask a junior dev, they'll say: "It's the login screen."
If you ask a senior dev, they'll say: "Authentication is identity; Authorization is permission."

But even seniors trip up when OAuth 2.0 enters the room.

This is the **Mastery Guide** to the Security Trinity. We'll start with a clean mental model, then dive into JWT debugging, the crucial difference between 401 and 403, and why OAuth is like a Valet Key.

***

## Part 1: Foundations (The Mental Model)

### The Trinity

| Term | Abbreviation | The Question | The Real-World Object |
|:---|:---|:---|:---|
| **Authentication** | **AuthN** | "Who the hell are you?" | **ID Card (Passport)** |
| **Authorization** | **AuthZ** | "Are you allowed to do this?" | **Gym Keycard** |
| **OAuth** | **Delegation** | "Can *he* do this *for* you?" | **Valet Key** |

### The "Luxury Condo" Analogy

Imagine you live in a high-tech luxury condo.

*   **AuthN (The Doorman)**: You walk up to the building. The doorman looks at your face (or ID). "Ah, hello Mr. Hoang."
    *   *Result*: You are **Authenticated**. You are inside the lobby.

*   **AuthZ (The Elevator)**: You swipe your keycard to go to the Penthouse. The elevator buzzes: *beep-beep*. "Access Denied." You live on the 2nd floor, not the Penthouse.
    *   *Result*: you are Authenticated (we know who you are), but **Unauthorized** (you can't go there).

*   **OAuth (The Dog Walker)**: You are away at work. You give your dog walker a key. But it's a special key - it only opens the Service Entrance and the Living Room. It doesn't open your Bedroom or Safe.
    *   *Result*: You **Delegated** access to someone else, with limited scope.

***

## Part 2: The Investigation (Debug Like a Pro)

In the API world, your "ID Card" is usually a **JWT (JSON Web Token)**. If Auth breaks, don't guess - inspect the token.

### 1. The "X-Ray Vision" (JWT.io)

A JWT is not encrypted; it's just Base64-encoded. **Anyone can read it.**

Take that `ey...` string and paste it into [jwt.io](https://jwt.io).

**What to look for in the Payload:**
*   `sub` (Subject): The User ID. (Is this the user you think it is?)
*   `exp` (Expiration): The Unix timestamp. (Is it expired?)
*   `scope` or `roles`: The permissions. (Does it have `admin` or just `viewer`?)

### 2. The Signature Check

If the token looks correct but the server rejects it, the **Signature** is wrong.
*   **Symmetric (HS256)**: The API needs the same "secret key" that signed the token.
*   **Asymmetric (RS256)**: The API needs the **Public Key** to verify the signature made by the Auth Server's **Private Key**.

> **Pro Tip**: If your API says "Invalid Signature", 90% of the time you rotated the keys on the Auth Server but forgot to update the API's Public Key.

***

## Part 3: The Diagnosis (Error Codes Decoded)

The HTTP status code tells you exactly which part of the flow failed.

### 401 vs. 403 (The Most Common Debate)

| Code | Name | Meaning | The Doorman Says... | Fix It By... |
|:---|:---|:---|:---|:---|
| **401** | **Unauthorized** | **Identity Missing/Bad**. | "I don't know you. Show me your ID." | Logging in again. Sending a valid `Authorization: Bearer` header. |
| **403** | **Forbidden** | **Permission Denied**. | "I know you are Hoang, but you can't enter the Penthouse." | Asking for more permissions (Upgrade account). |

> **Stop saying "401 Unauthorized" means permission denied.** It means *Authentication* failed. 403 means *Authorization* failed. Blame the HTTP spec for naming 401 purely.

***

## Part 4: The Resolution (Code Patterns)

### 1. The OAuth "Dance" (Valet Key)

How does "Log in with Google" actually work? It is **giving a Valet Key** to your app.

1.  **User** says "I want to log in".
2.  **App** sends User to Google's "Key Counter" (Authorization Server).
3.  **User** tells Google: "Give this App a key that can *only* read my Email." (Scope).
4.  **Google** hands the App a special code.
5.  **App** trades that code for an **Access Token** (The Valet Key).

### 2. Python Cookbook: Verifying a JWT

Don't write your own crypto. Use `PyJWT`.

```python
import jwt

token = "ey..."
public_key_pem = "-----BEGIN PUBLIC KEY..."

try:
    # 1. Decode & Verify Signature
    # 2. Check Expiration (exp) automatically
    payload = jwt.decode(token, public_key_pem, algorithms=["RS256"])
    
    print(f"Hello, User {payload['sub']}")

except jwt.ExpiredSignatureError:
    print("401: Token Expired. Please refresh.")
except jwt.InvalidTokenError:
    print("401: Fake Token. Begone, hacker!")
```

### 3. Python Cookbook: Handling 403 (Role Check)

```python
# The token is valid (Authentication passed), now check Permissions (Authorization)
user_roles = payload.get("roles", [])

if "admin" not in user_roles:
    # We know who you are, but you can't touch this.
    raise PermissionDenied("403: You need Admin access for this.")
```

***

## Final Mental Model

```
AuthN (401) -> "Who are you?" (ID Card)
AuthZ (403) -> "Can you do this?" (Gym Keycard)
OAuth       -> "Can this App act as you?" (Valet Key)

JWT         -> The actual plastic card. 
               (Don't accept it if the expiry date is scratched off).
```

If you remember **"ID Card vs. Keycard"**, you'll never mix up Authentication and Authorization again.
