๐Ÿ“ Fastapi

JWT Authentication in FastAPI

P
Author
PyLand Team
๐Ÿ“…
Published
30.06.2026
โฑ๏ธ
Reading time
1 min
๐Ÿ‘๏ธ
Views
307
๐ŸŒณ
Level
Advanced

Covered topics: Installation, Configuration, Password and Token Utilities, Token Endpoint.

Installation

uv add "pyjwt[crypto]" "pwdlib[argon2]" python-multipart

Configuration

import os
from datetime import datetime, timedelta, timezone

import jwt
from jwt.exceptions import InvalidTokenError
from pwdlib import PasswordHash
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

SECRET_KEY = os.environ["JWT_SECRET_KEY"]
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

password_hash = PasswordHash.recommended()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/token")

Password and Token Utilities

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

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

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["exp"] = expire
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

Token Endpoint

@router.post("/token")
def login(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db: Session = Depends(get_session),
):
    user = db.exec(select(User).where(User.username == form_data.username)).first()
    if not user or not verify_password(form_data.password, user.hashed_password):
        raise HTTPException(status_code=401, detail="Invalid credentials")

    access_token = create_access_token(
        data={"sub": str(user.id)},
        expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES),
    )
    return {"access_token": access_token, "token_type": "bearer"}

Current User Dependency

def get_current_user(
    token: str = Depends(oauth2_scheme),
    db: Session = Depends(get_session),
) -> User:
    credentials_exception = HTTPException(status_code=401, detail="Invalid token")
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id = payload.get("sub")
        if user_id is None:
            raise credentials_exception
    except InvalidTokenError:
        raise credentials_exception

    user = db.get(User, int(user_id))
    if user is None:
        raise credentials_exception
    return user

@app.get("/tasks/")
def list_tasks(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_session),
):
    statement = select(Task).where(Task.owner_id == current_user.id)
    return db.exec(statement).all()

Your reaction to the article

๐Ÿ’ฌ Comments (0)

๐Ÿ” Sign in to leave a comment
๐Ÿšช Login
๐Ÿ’ญ

No comments yet

Be the first to share your opinion about this article!

๐Ÿ”— Similar

Similar articles

Continue learning with these materials

๐Ÿ“

OAuth2 Bearer in FastAPI

OAuth2PasswordBearer is FastAPI's Bearer token authentication scheme.

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 387
๐Ÿ“

Middleware and CORS in FastAPI

Middleware processes requests and responses around FastAPI routes, while CORS controls which browser origins may...

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 330
๐Ÿ“

HTTPException in FastAPI

Covered topics: Basic Usage, Status Codes, Error Details, Custom Headers.

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 298
๐ŸŽ“ Continue learning

Courses that cover this material

Visit the course to apply this material in practice.

FastAPI: From First Route to an AI-Powered Site Open course curriculum