# JWT Operations

Core JWT encoding and decoding functionality with comprehensive claim validation, expiration checking, and signature verification. Supports all standard JWT claims and custom payloads with flexible verification options.

## Capabilities

### JWT Encoding

Creates signed JSON Web Tokens from payload dictionaries with automatic datetime conversion and header management.

```python { .api }
def encode(payload: dict, key: str | bytes, algorithm: str = 'HS256', 
          headers: dict = None, json_encoder = None, sort_headers: bool = True) -> str:
    """
    Encode a payload as a JSON Web Token.

    Args:
        payload (dict): Claims to encode in the token
        key (str | bytes): Secret key or private key for signing
        algorithm (str): Signing algorithm ('HS256', 'RS256', etc.)
        headers (dict): Additional headers for the JWT
        json_encoder: Custom JSON encoder class
        sort_headers (bool): Sort header keys alphabetically

    Returns:
        str: Encoded JWT token

    Raises:
        TypeError: If payload is not a dictionary
        InvalidKeyError: If key is invalid for algorithm
    """
```

Usage example:

```python
import jwt
from datetime import datetime, timedelta, timezone

# Simple payload
payload = {'user_id': 123, 'role': 'admin'}
token = jwt.encode(payload, 'secret', algorithm='HS256')

# With expiration and custom claims
payload = {
    'user_id': 123,
    'exp': datetime.now(tz=timezone.utc) + timedelta(hours=1),
    'iat': datetime.now(tz=timezone.utc),
    'aud': 'my-app',
    'iss': 'auth-service'
}
token = jwt.encode(payload, 'secret', algorithm='HS256')

# With custom headers
headers = {'kid': 'key-1', 'custom': 'value'}
token = jwt.encode(payload, 'secret', algorithm='HS256', headers=headers)
```

### JWT Decoding

Decodes and validates JSON Web Tokens with comprehensive claim verification and flexible validation options.

```python { .api }
def decode(jwt: str | bytes, key: str | bytes = '', algorithms: list = None,
          options: dict = None, verify: bool = None, detached_payload: bytes = None,
          audience: str | list = None, issuer: str | list = None,
          subject: str = None, leeway: float | timedelta = 0) -> dict:
    """
    Decode and verify a JSON Web Token.

    Args:
        jwt (str | bytes): JWT token to decode
        key (str | bytes): Secret key or public key for verification
        algorithms (list): Allowed algorithms for verification
        options (dict): Verification options
        audience (str | list): Expected audience(s)
        issuer (str | list): Expected issuer(s)  
        subject (str): Expected subject
        leeway (float | timedelta): Clock skew tolerance in seconds

    Returns:
        dict: Decoded payload

    Raises:
        DecodeError: Token format errors
        InvalidSignatureError: Signature verification failed
        ExpiredSignatureError: Token has expired
        InvalidAudienceError: Audience validation failed
        InvalidIssuerError: Issuer validation failed
        MissingRequiredClaimError: Required claim missing
    """

def decode_complete(jwt: str | bytes, key: str | bytes = '', algorithms: list = None,
                   options: dict = None, audience: str | list = None,
                   issuer: str | list = None, subject: str = None,
                   leeway: float | timedelta = 0) -> dict:
    """
    Decode JWT returning header, payload, and signature.

    Returns:
        dict: {'header': dict, 'payload': dict, 'signature': bytes}
    """
```

Usage examples:

```python
import jwt
from jwt.exceptions import ExpiredSignatureError, InvalidTokenError

# Basic decoding
try:
    payload = jwt.decode(token, 'secret', algorithms=['HS256'])
    print(f"User: {payload['user_id']}")
except InvalidTokenError as e:
    print(f"Invalid token: {e}")

# With claim validation
try:
    payload = jwt.decode(
        token, 
        'secret', 
        algorithms=['HS256'],
        audience='my-app',
        issuer='auth-service',
        leeway=10  # 10 second clock skew tolerance
    )
except ExpiredSignatureError:
    print("Token expired")
except InvalidAudienceError:
    print("Wrong audience")

# Get complete token structure
decoded = jwt.decode_complete(token, 'secret', algorithms=['HS256'])
print(f"Header: {decoded['header']}")
print(f"Payload: {decoded['payload']}")
```

### PyJWT Class

Object-oriented interface for JWT operations with configurable default options and reusable instances.

```python { .api }
class PyJWT:
    def __init__(self, options: dict = None):
        """
        Initialize JWT instance with default options.

        Args:
            options (dict): Default verification options
        """

    def encode(self, payload: dict, key, algorithm: str = None, 
              headers: dict = None, json_encoder = None, 
              sort_headers: bool = True) -> str:
        """Encode JWT with instance options."""

    def decode(self, jwt: str | bytes, key = '', algorithms: list = None,
              options: dict = None, audience: str | list = None,
              issuer: str | list = None, subject: str = None,
              leeway: float | timedelta = 0) -> dict:
        """Decode JWT with instance options."""

    def decode_complete(self, jwt: str | bytes, key = '', 
                       algorithms: list = None, options: dict = None,
                       audience: str | list = None, issuer: str | list = None,
                       subject: str = None, leeway: float | timedelta = 0) -> dict:
        """Decode complete JWT with instance options."""
```

Usage example:

```python
# Create instance with custom defaults
jwt_instance = jwt.PyJWT(options={
    'verify_exp': True,
    'verify_aud': True,
    'require': ['exp', 'aud']
})

# Use instance methods
token = jwt_instance.encode({'user_id': 123}, 'secret')
payload = jwt_instance.decode(token, 'secret', algorithms=['HS256'])
```

## Verification Options

The `options` dictionary controls JWT validation behavior:

```python { .api }
# Default verification options
{
    'verify_signature': True,  # Verify signature
    'verify_exp': True,        # Verify expiration time
    'verify_nbf': True,        # Verify not before time
    'verify_iat': True,        # Verify issued at time
    'verify_aud': True,        # Verify audience
    'verify_iss': True,        # Verify issuer
    'verify_sub': True,        # Verify subject
    'verify_jti': True,        # Verify JWT ID
    'require': []              # List of required claims
}
```

Usage example:

```python
# Disable expiration checking
options = {'verify_exp': False}
payload = jwt.decode(token, 'secret', algorithms=['HS256'], options=options)

# Require specific claims
options = {'require': ['aud', 'iss', 'exp']}
payload = jwt.decode(token, 'secret', algorithms=['HS256'], options=options)
```

## Supported Algorithms

### HMAC Algorithms (Symmetric)
- **HS256**: HMAC using SHA-256 (default)
- **HS384**: HMAC using SHA-384  
- **HS512**: HMAC using SHA-512

### RSA Algorithms (Asymmetric)
- **RS256**: RSASSA-PKCS1-v1_5 using SHA-256
- **RS384**: RSASSA-PKCS1-v1_5 using SHA-384
- **RS512**: RSASSA-PKCS1-v1_5 using SHA-512
- **PS256**: RSASSA-PSS using SHA-256
- **PS384**: RSASSA-PSS using SHA-384
- **PS512**: RSASSA-PSS using SHA-512

### ECDSA Algorithms (Asymmetric)
- **ES256**: ECDSA using P-256 and SHA-256
- **ES384**: ECDSA using P-384 and SHA-384
- **ES512**: ECDSA using P-521 and SHA-512
- **ES256K**: ECDSA using secp256k1 and SHA-256

### EdDSA Algorithms (Asymmetric)
- **EdDSA**: EdDSA using Ed25519 or Ed448

Note: RSA, ECDSA, and EdDSA algorithms require the `cryptography` library (`pip install PyJWT[crypto]`).