Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Working with JSON Web Tokens in Python Using PyJWT

Tech May 13 1

What is PyJWT?

PyJWT is a Python library designed for creating, parsing, and validating JSON Web Tokens (JWT). JWT is a compact, self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. PyJWT simplifies the implementation of JWT in Python applications, providing a robust set of features for token-based authentication and data transmission.

Installing PyJWT

To begin using PyJWT, you'll need to install it first. The simplest way to install PyJWT is using pip:
pip install PyJWT
Once installed, you can import the library into your Python scripts:
import jwt

Core JWT Concepts

Before diving into implementation, it's essential to understand the fundamental components of JWT: - **Token**: The encoded string that carries information between parties. - **Header**: Contains metadata about the token, including the signing algorithm and token type. - **Payload**: Contains the claims, which are statements about an entity (typically a user) and additional data. - **Signature**: The cryptographic signature used to verify the token's integrity and authenticity. - **Algorithm**: The cryptographic method used to sign and verify the token, such as HS256, RS256, etc.

Creating JWT Tokens

Here's how you can create a JWT token using PyJWT:
import jwt
import datetime

# Define payload data
payload_data = {
    'user_id': 42,
    'username': 'john_doe',
    'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}

# Generate JWT token
secret_key = 'your-secret-key-here'
token = jwt.encode(payload_data, secret_key, algorithm='HS256')

print(token)
This example creates a token with user information and sets an expiration time one hour from now.

Parsing JWT Tokens

To decode a JWT token without verifying its signature:
import jwt

# Token received from client
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo0MiwidXNlcm5hbWUiOiJqb2huX2RvZSIsImV4cCI6MTYwODkxNzkwMH0.abcdef123456"

# Decode token without verification
decoded = jwt.decode(token, options={"verify_signature": False})

print(decoded)

Verifying JWT Tokens

For security-critical applications, you should verify the token signature:
import jwt

# Token received from client
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo0MiwidXNlcm5hbWUiOiJqb2huX2RvZSIsImV4cCI6MTYwODkxNzkwMH0.abcdef123456"

# Secret key used for signing
secret_key = 'your-secret-key-here'

try:
    # Verify and decode token
    decoded = jwt.decode(token, secret_key, algorithms=['HS256'])
    print("Token is valid:", decoded)
except jwt.ExpiredSignatureError:
    print("Token has expired")
except jwt.InvalidTokenError:
    print("Invalid token")

Advanced Features and Use Cases

Custom Expiration Handling

PyJWT allows for flexible expiration handling:
import jwt
import datetime

# Create token with custom expiration
payload = {
    'user_id': 42,
    'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
}

token = jwt.encode(payload, 'secret', algorithm='HS256')

# Check expiration manually
decoded = jwt.decode(token, options={"verify_signature": False})
if decoded['exp'] < datetime.datetime.utcnow().timestamp():
    print("Token has expired")
else:
    print("Token is still valid")

Selecting Encryption Algorithms

PyJWT supports various algorithms for signing tokens:
import jwt

# Using HMAC with SHA-256 (HS256)
payload = {'user_id': 42}
token_hs256 = jwt.encode(payload, 'secret', algorithm='HS256')

# Using RSA with SHA-256 (RS256)
# Note: You would need to generate/load your RSA keys
private_key = """-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...your private key here...
-----END RSA PRIVATE KEY-----"""
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...your public key here...
-----END PUBLIC KEY-----"""

token_rs256 = jwt.encode(payload, private_key, algorithm='RS256')

# Verify with public key
decoded = jwt.decode(token_rs256, public_key, algorithms=['RS256'])

Refresh Tokens

Implementing refresh tokens for maintaining user sessions:
import jwt
import datetime

def generate_tokens(user_id):
    """Generate access and refresh tokens for a user"""
    
    # Access token with short expiration
    access_payload = {
        'user_id': user_id,
        'type': 'access',
        'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
    }
    access_token = jwt.encode(access_payload, 'access-secret', algorithm='HS256')
    
    # Refresh token with longer expiration
    refresh_payload = {
        'user_id': user_id,
        'type': 'refresh',
        'exp': datetime.datetime.utcnow() + datetime.timedelta(days=7)
    }
    refresh_token = jwt.encode(refresh_payload, 'refresh-secret', algorithm='HS256')
    
    return access_token, refresh_token

def refresh_access_token(refresh_token):
    """Generate a new access token using a valid refresh token"""
    try:
        # Verify refresh token
        payload = jwt.decode(refresh_token, 'refresh-secret', algorithms=['HS256'])
        
        # Check if it's a refresh token
        if payload.get('type') != 'refresh':
            raise jwt.InvalidTokenError("Invalid token type")
            
        # Generate new access token
        access_payload = {
            'user_id': payload['user_id'],
            'type': 'access',
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
        }
        return jwt.encode(access_payload, 'access-secret', algorithm='HS256')
        
    except jwt.ExpiredSignatureError:
        raise Exception("Refresh token has expired")
    except jwt.InvalidTokenError:
        raise Exception("Invalid refresh token")

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.