Thursday, 20 November 2025

#7 JWT Authentication — Login, Protect Routes, Verify Token

๐Ÿ“„ POST 7 — Module 7 (JWT Authentication — Login, Protect Routes, Verify Token)

Includes:
✔ What is JWT
✔ Creating access tokens
✔ Implementing /login
✔ Protecting routes with JWT
✔ Verifying user credentials
✔ Using OAuth2PasswordBearer

All code blocks include Prism.js syntax highlighting, Copy button, and Download button.


<!doctype html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>FastAPI Module 7 — JWT Authentication</title>

  <!-- Prism.js Theme -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-okaidia.min.css" rel="stylesheet"/>

  <style>
    body{font-family:Inter,Arial;background:#0f1724;color:#e6eef8;padding:20px;line-height:1.6}
    .box{max-width:900px;margin:auto;background:rgba(255,255,255,0.04);padding:22px;border-radius:12px}
    h1{margin-top:0}
    pre{position:relative;border-radius:8px;overflow:auto}
    .code-actions{position:absolute;top:8px;right:8px;display:flex;gap:6px;z-index:3}
    .code-actions button{background:#0006;border:0;padding:6px 8px;color:#fff;border-radius:6px;cursor:pointer;font-size:13px}
    .nav{margin-top:25px;padding:14px;background:#0003;border-radius:10px}
    .nav a{color:#8ad0ff;margin-right:20px;text-decoration:none}
  </style>
</head>

<body>
<div class="box">

<h1>Module 7 — JWT Authentication in FastAPI</h1>
<p>
JSON Web Tokens (JWT) allow stateless authentication.  
FastAPI provides built-in support for OAuth2 (password flow) and token-based authentication.
</p>

<hr>

<h2>๐Ÿ” 1. Install JWT Library</h2>

<pre>
<div class="code-actions">
<button class="copy-btn">Copy</button>
<button class="dl-btn">Download (.txt)</button>
</div>
<code class="language-bash" data-filename="install_jwt.txt">pip install python-jose passlib[bcrypt]</code></pre>

<hr>

<h2>๐Ÿ”‘ 2. Create Token Generator</h2>
<p>We use <code>python-jose</code> to create and verify JWT tokens.</p>

<pre>
<div class="code-actions">
<button class="copy-btn">Copy</button>
<button class="dl-btn">Download (.py)</button>
</div>
<code class="language-python" data-filename="jwt_utils.py">from datetime import datetime, timedelta
from jose import jwt

SECRET_KEY = "mysecretjwtkey"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt</code></pre>

<hr>

<h2>๐Ÿ‘ค 3. Fake User Database + Password Verification</h2>

<pre>
<div class="code-actions"><button class="copy-btn">Copy</button>
<button class="dl-btn">Download (.py)</button></div>
<code class="language-python" data-filename="users_db.py">from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

fake_users = {
    "john": {
        "username": "john",
        "full_name": "John Doe",
        "hashed_password": pwd_context.hash("secret123")
    }
}

def verify_password(plain, hashed):
    return pwd_context.verify(plain, hashed)

def authenticate_user(username: str, password: str):
    user = fake_users.get(username)
    if not user:
        return False
    if not verify_password(password, user["hashed_password"]):
        return False
    return user</code></pre>

<hr>

<h2>๐Ÿ” 4. Implement OAuth2 Login</h2>

<pre>
<div class="code-actions"><button class="copy-btn">Copy</button>
<button class="dl-btn">Download (.py)</button></div>
<code class="language-python" data-filename="jwt_login.py">from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from jwt_utils import create_access_token
from users_db import authenticate_user

app = FastAPI()

@app.post("/login")
async def login(form: OAuth2PasswordRequestForm = Depends()):
    user = authenticate_user(form.username, form.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid username or password",
        )

    access_token = create_access_token({"sub": user["username"]})
    return {"access_token": access_token, "token_type": "bearer"}</code></pre>

<hr>

<h2>๐Ÿ›ก 5. Protect Routes Using JWT</h2>

<pre>
<div class="code-actions"><button class="copy-btn">Copy</button>
<button class="dl-btn">Download (.py)</button></div>
<code class="language-python" data-filename="jwt_protected.py">from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError
from jwt_utils import SECRET_KEY, ALGORITHM
from main import app

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login")

def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username = payload.get("sub")
        if username is None:
            raise HTTPException(status_code=401, detail="Invalid token")
        return username
    except JWTError:
        raise HTTPException(status_code=401, detail="Token validation failed")

@app.get("/profile")
async def profile(username: str = Depends(get_current_user)):
    return {"authenticated_as": username}</code></pre>

<hr>

<h2>๐Ÿงช 6. Test Your JWT Authentication</h2>

### **1. Login to receive token**
POST → `/login`

Body (form-data):

username=john
password=secret123


### **2. Then call:**

GET /profile
Authorization: Bearer


---

<div class="nav">
  <strong>← Previous Module:</strong>
  <a href="POST_URL_MODULE_6">Module 6 — Middleware, CORS & Events</a><br><br>

  <strong>Next Module →</strong>
  <a href="POST_URL_MODULE_8">Module 8 — Background Tasks</a>
</div>

</div>

<!-- Prism.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js"></script>

<script>
document.querySelectorAll('pre').forEach(pre=>{
  let codeEl = pre.querySelector('code');
  if(!codeEl) return;

  let code = codeEl.innerText;
  let filename = codeEl.dataset.filename || "snippet.txt";

  let copyBtn = pre.querySelector('.copy-btn');
  let dlBtn = pre.querySelector('.dl-btn');

  copyBtn.onclick = () => {
    navigator.clipboard.writeText(code);
    copyBtn.textContent = "Copied ✓";
    setTimeout(()=> copyBtn.textContent = "Copy", 1200);
  };

  dlBtn.onclick = () => {
    let blob = new Blob([code], {type:"text/plain"});
    let url = URL.createObjectURL(blob);
    let a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.click();
  };
});
</script>

</body>
</html>


No comments:

Post a Comment

Diagnosis for running all Scripts

 Great — here is the complete ready-to-run folder structure for all 12 FastAPI modules , including: ✅ __init__.py (so Python treats folder...