📝 Python

JWT Tokens with python-jose

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
1 min
👁️
Views
105
📊
Level
Article

python-jose is a library for working with JSON Web Tokens (JWT).

Installation

pip install python-jose[cryptography]

Creating a token

from jose import jwt
from datetime import datetime, timedelta

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

def create_access_token(data: dict, expires_minutes: int = 30) -> str:
    payload = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=expires_minutes)
    payload["exp"] = expire
    payload["iat"] = datetime.utcnow()  # issued at
    return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)

Decoding a token

from jose import JWTError, jwt

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

# Usage
token = create_access_token({"sub": "user_id_42", "role": "admin"})
payload = decode_token(token)
# {'sub': 'user_id_42', 'role': 'admin', 'exp': 1234567890, 'iat': ...}

Access and Refresh tokens

def create_tokens(user_id: int) -> dict:
    access_token = create_access_token(
        data={"sub": str(user_id), "type": "access"},
        expires_minutes=30,
    )
    refresh_token = create_access_token(
        data={"sub": str(user_id), "type": "refresh"},
        expires_minutes=60 * 24 * 7,  # 7 days
    )
    return {
        "access_token": access_token,
        "refresh_token": refresh_token,
        "token_type": "bearer",
    }

def refresh_access_token(refresh_token: str) -> str | None:
    payload = decode_token(refresh_token)
    if not payload or payload.get("type") != "refresh":
        return None
    return create_access_token({"sub": payload["sub"], "type": "access"})

RS256 (asymmetric cryptography)

from jose import jwt

# Generating keys:
# openssl genrsa -out private.pem 2048
# openssl rsa -in private.pem -pubout -out public.pem

with open("private.pem") as f:
    private_key = f.read()
with open("public.pem") as f:
    public_key = f.read()

# Sign with the private key
token = jwt.encode({"sub": "1"}, private_key, algorithm="RS256")

# Verify with the public key
payload = jwt.decode(token, public_key, algorithms=["RS256"])

JWT structure

eyJhbGciOiJIUzI1NiJ9  ← Header (base64)
.eyJzdWIiOiIxIn0       ← Payload (base64)
.abc123signature        ← Signature (HMAC)

JWT is signed, not encrypted. Never store secrets in the payload!

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

📝

Event Loop in Python: How asyncio Achieves "Paral…

Event loop is the heart of asyncio. It doesn't run code in parallel across multiple...

📅 30.06.2026 👁️ 121
📝

pytest-django: Testing Django

Охватываемые темы: Installation, @pytest.mark.djangodb, Fixtures, Testing views.

📅 30.06.2026 👁️ 130
📝

pip: Python Package Manager

Охватываемые темы: Installing packages, Upgrading and removing, requirements.txt, Virtual environment.

📅 30.06.2026 👁️ 117

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!