Back to list
jamaliumair

jwt-auth

by jamaliumair

0🍴 0📅 Jan 11, 2026

SKILL.md


name: jwt-auth description: | JWT (JSON Web Token) authentication skill for Python web applications. Use when: (1) Implementing token-based authentication, (2) Creating login/register endpoints, (3) Setting up access and refresh tokens, (4) Adding password hashing with Argon2/bcrypt, (5) Creating protected route dependencies, (6) Implementing role-based access control (RBAC), (7) Adding OAuth2 scopes, (8) Token blacklisting/revocation strategies.

JWT Authentication Skill

Comprehensive JWT authentication patterns for Python APIs (FastAPI, Flask, etc.).

Quick Reference

FeatureReference File
Token creation, validation, refreshreferences/tokens.md
Password hashing (Argon2, bcrypt)references/password-hashing.md
Protected routes, RBACreferences/protected-routes.md

Dependencies

[project]
dependencies = [
    "python-jose[cryptography]>=3.3.0",  # JWT encoding/decoding
    "passlib[bcrypt]>=1.7.4",            # Password hashing
    "argon2-cffi>=23.1.0",               # Argon2 (recommended)
]

JWT Basics

Token Structure

header.payload.signature

Header:  {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "user_id", "exp": 1234567890, "iat": 1234567800}
Signature: HMACSHA256(base64(header) + "." + base64(payload), secret)

Core Security Module

from datetime import datetime, timedelta, timezone
from jose import JWTError, jwt
from passlib.context import CryptContext

SECRET_KEY = "your-secret-key-min-32-chars"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

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

def verify_password(plain: str, hashed: str) -> bool:
    return pwd_context.verify(plain, hashed)

def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=15))
    to_encode.update({"exp": expire, "type": "access"})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

def decode_token(token: str) -> dict | None:
    try:
        return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    except JWTError:
        return None

FastAPI Integration

OAuth2 Password Bearer

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/login")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    payload = decode_token(token)
    if not payload or payload.get("type") != "access":
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token",
            headers={"WWW-Authenticate": "Bearer"},
        )
    user_id = payload.get("sub")
    # Fetch user from database
    return user

Login Endpoint

from fastapi.security import OAuth2PasswordRequestForm

@router.post("/login")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = await get_user_by_email(form_data.username)
    if not user or not verify_password(form_data.password, user.hashed_password):
        raise HTTPException(401, "Invalid credentials")

    return {
        "access_token": create_access_token({"sub": str(user.id)}),
        "token_type": "bearer"
    }

Token Pair Pattern (Access + Refresh)

def create_token_pair(user_id: int) -> dict:
    return {
        "access_token": create_access_token({"sub": str(user_id)}),
        "refresh_token": create_refresh_token({"sub": str(user_id)}),
        "token_type": "bearer",
    }

def create_refresh_token(data: dict) -> str:
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + timedelta(days=7)
    to_encode.update({"exp": expire, "type": "refresh"})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

@router.post("/refresh")
async def refresh(refresh_token: str):
    payload = decode_token(refresh_token)
    if not payload or payload.get("type") != "refresh":
        raise HTTPException(401, "Invalid refresh token")
    return create_token_pair(int(payload["sub"]))

Environment Variables

JWT_SECRET_KEY=your-super-secret-key-at-least-32-characters
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7

Security Best Practices

  1. Secret Key: Use 256+ bit random key, never commit to git
  2. Token Expiry: Short-lived access tokens (15-30 min), longer refresh tokens
  3. HTTPS Only: Always use HTTPS in production
  4. Password Hashing: Use Argon2 (preferred) or bcrypt, never SHA/MD5
  5. Token Storage: Store in httpOnly cookies or secure storage, not localStorage

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon