๐ 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