JWT Login & Authentication
Crunchyroll Downloader — Practical Scripting
Course 1 · Chapter 3 · JWT Login & Authentication
🔐 JWT Login & Authentication
Learn how to authenticate with Crunchyroll using email/password, receive a JWT token, cache it for reuse, and handle token expiration. This is the core of JWT-based API authentication.
🔑 The Login Flow
import requests
import json
from pathlib import Path
from datetime import datetime
def login(config) -> str:
"""Login to Crunchyroll and get JWT token."""
url = f"{config.api_base}/auth/v1/authenticate"
payload = {
"username": config.email,
"password": config.password,
"grant_type": "password"
}
try:
# POST request to login endpoint
response = requests.post(url, json=payload, timeout=10)
if response.status_code != 200:
print(f"❌ Login failed: {response.status_code}")
print(response.json())
return None
data = response.json()
token = data.get('access_token')
if not token:
print("❌ No token in response")
return None
print("✅ Login successful!")
return token
except Exception as e:
print(f"❌ Login error: {e}")
return None
💾 Caching the Token
def save_token(token: str, cache_file: str):
"""Save token to file for reuse."""
data = {
"token": token,
"timestamp": datetime.now().isoformat()
}
with open(cache_file, 'w') as f:
json.dump(data, f)
print(f"✅ Token cached to {cache_file}")
def load_cached_token(cache_file: str) -> str:
"""Load cached token if it exists."""
if not Path(cache_file).exists():
return None
try:
with open(cache_file, 'r') as f:
data = json.load(f)
return data.get("token")
except:
return None
📝 Using the Token in Requests
def get_with_token(url: str, token: str) -> dict:
"""Make GET request with JWT token."""
headers = {
"Authorization": f"Bearer {token}",
"User-Agent": "Mozilla/5.0"
}
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 401:
print("❌ Token expired or invalid")
return None
if response.status_code == 200:
return response.json()
print(f"❌ Request failed: {response.status_code}")
return None
except Exception as e:
print(f"❌ Error: {e}")
return None
💻 Coding Challenges
Challenge 1: Implement Login
Create login() function that authenticates with Crunchyroll and returns JWT token.
Challenge 2: Token Caching
Implement save_token() and load_cached_token() to avoid re-logging in.
Challenge 3: Authenticated Requests
Create get_with_token() that includes JWT in Authorization header.