Skip to main content

A simple, secure, and universal JWT library for web and mobile applications

Project description

SCG JWT Token for Python

A simple, secure, and universal JWT library for web and mobile applications.

Installation

pip install scg-jwt-token

Quick Start

from scg_jwt_token import SCGJwtToken

# Create JWT instance
jwt = SCGJwtToken("your-secret-key")

# Create token
token = jwt.sign({
    "user_id": 123,
    "email": "user@example.com",
    "role": "user"
})

# Verify token
try:
    payload = jwt.verify(token)
    print(f"User: {payload['email']}")
except ValueError as e:
    print(f"Invalid token: {e}")

Features

  • Stateless: No database storage needed for tokens
  • Secure: Uses HMAC SHA-256 with proper JWT standards
  • Universal: Works with web apps, mobile apps, APIs, and microservices
  • Zero Dependencies: Pure Python implementation
  • Type Hints: Full TypeScript-style type annotations
  • Production Ready: Comprehensive error handling and validation

API Reference

SCGJwtToken

Constructor

jwt = SCGJwtToken(secret_key)

Methods

sign(payload, expires_in=3600, issuer=None, audience=None)

Create a JWT token.

token = jwt.sign(
    {"user_id": 123, "role": "admin"},
    expires_in=86400,  # 24 hours
    issuer="my-app",
    audience="app-users"
)

verify(token, issuer=None, audience=None)

Verify and decode a token.

payload = jwt.verify(token)

decode(token)

Decode without verification (for debugging).

decoded = jwt.decode(token)
print(decoded['header'])
print(decoded['payload'])

is_expired(token)

Check if token is expired.

if jwt.is_expired(token):
    print("Token expired")

refresh(token, expires_in=3600)

Create new token with updated expiration.

new_token = jwt.refresh(old_token, expires_in=86400)

get_stats()

Get performance statistics.

stats = jwt.get_stats()
print(f"Tokens created: {stats['tokens_created']}")

Quick Operations

from scg_jwt_token import QuickJWT

# Quick sign with auto-generated secret
result = QuickJWT.quick_sign({"user_id": 123})
print(f"Token: {result['token']}")
print(f"Secret: {result['secret']}")

# Quick verify
payload = QuickJWT.quick_verify(token, secret)

Web Framework Examples

Flask

from flask import Flask, request, jsonify
from scg_jwt_token import SCGJwtToken
import os

app = Flask(__name__)
jwt = SCGJwtToken(os.getenv('JWT_SECRET'))

@app.route('/api/login', methods=['POST'])
def login():
    # Validate user credentials here
    user = validate_user(request.json['email'], request.json['password'])

    if user:
        token = jwt.sign({
            'user_id': user['id'],
            'email': user['email'],
            'role': user['role']
        }, expires_in=86400)

        return jsonify({'token': token, 'user': user})

    return jsonify({'error': 'Invalid credentials'}), 401

@app.route('/api/protected', methods=['GET'])
def protected():
    auth_header = request.headers.get('Authorization')
    if not auth_header or not auth_header.startswith('Bearer '):
        return jsonify({'error': 'Token required'}), 401

    token = auth_header.split(' ')[1]

    try:
        user = jwt.verify(token)
        return jsonify({'message': 'Access granted', 'user': user})
    except ValueError:
        return jsonify({'error': 'Invalid token'}), 403

Django

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from scg_jwt_token import SCGJwtToken
import json
import os

jwt = SCGJwtToken(os.getenv('JWT_SECRET'))

@csrf_exempt
def login_view(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        user = authenticate_user(data['email'], data['password'])

        if user:
            token = jwt.sign({
                'user_id': user.id,
                'email': user.email,
                'role': user.role
            })
            return JsonResponse({'token': token})

        return JsonResponse({'error': 'Invalid credentials'}, status=401)

def protected_view(request):
    auth_header = request.META.get('HTTP_AUTHORIZATION')
    if not auth_header or not auth_header.startswith('Bearer '):
        return JsonResponse({'error': 'Token required'}, status=401)

    token = auth_header.split(' ')[1]

    try:
        user = jwt.verify(token)
        return JsonResponse({'user': user})
    except ValueError:
        return JsonResponse({'error': 'Invalid token'}, status=403)

FastAPI

from fastapi import FastAPI, HTTPException, Depends, Header
from scg_jwt_token import SCGJwtToken
import os

app = FastAPI()
jwt = SCGJwtToken(os.getenv('JWT_SECRET'))

async def verify_token(authorization: str = Header(None)):
    if not authorization or not authorization.startswith('Bearer '):
        raise HTTPException(status_code=401, detail='Token required')

    token = authorization.split(' ')[1]

    try:
        return jwt.verify(token)
    except ValueError:
        raise HTTPException(status_code=403, detail='Invalid token')

@app.post('/api/login')
async def login(credentials: dict):
    user = await authenticate_user(credentials['email'], credentials['password'])

    if user:
        token = jwt.sign({
            'user_id': user['id'],
            'email': user['email'],
            'role': user['role']
        })
        return {'token': token}

    raise HTTPException(status_code=401, detail='Invalid credentials')

@app.get('/api/protected')
async def protected(user: dict = Depends(verify_token)):
    return {'user': user}

Why JWT Over Sessions

Traditional Session-Based Auth

  • User Login → Create Session → Store in Database → Return Session ID
  • User Request → Database Lookup → Validate Session → Process Request
  • Every request = Database query = Slow & Resource Heavy

SCG JWT Token-Based Auth

  • User Login → Create JWT Token → Return Token (NO database storage)
  • User Request → Verify JWT Signature → Process Request
  • No database queries = Lightning Fast & Highly Scalable

Security Best Practices

  1. Use environment variables for secrets:

    jwt = SCGJwtToken(os.getenv('JWT_SECRET'))
    
  2. Set reasonable expiration times:

    token = jwt.sign(payload, expires_in=86400)  # 24 hours
    
  3. Always use HTTPS in production

  4. Validate tokens on server side:

    try:
        payload = jwt.verify(token)
    except ValueError as e:
        return error_response('Invalid token')
    
  5. Use proper Authorization headers:

    Authorization: Bearer <your-jwt-token>
    

Testing

import unittest
from scg_jwt_token import SCGJwtToken

class TestSCGJwt(unittest.TestCase):
    def setUp(self):
        self.jwt = SCGJwtToken("test-secret")

    def test_create_and_verify_token(self):
        payload = {"user_id": 123, "role": "admin"}
        token = self.jwt.sign(payload)

        decoded = self.jwt.verify(token)
        self.assertEqual(decoded['user_id'], 123)
        self.assertEqual(decoded['role'], "admin")

    def test_expired_token(self):
        token = self.jwt.sign({"user_id": 123}, expires_in=-1)

        with self.assertRaises(ValueError):
            self.jwt.verify(token)

if __name__ == '__main__':
    unittest.main()

Use Cases

Perfect for:

  • Web Applications: Flask, Django, FastAPI applications
  • Mobile APIs: REST APIs for mobile apps
  • Microservices: Service-to-service authentication
  • Single Page Apps: React, Vue, Angular frontends
  • Cross-platform: Same authentication across all platforms

Requirements

  • Python 3.7+
  • No external dependencies

License

MIT License

Support

Built by Analytics With Harry and Squid Consultancy Group Limited.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scg_jwt_token-2.0.0.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scg_jwt_token-2.0.0-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file scg_jwt_token-2.0.0.tar.gz.

File metadata

  • Download URL: scg_jwt_token-2.0.0.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for scg_jwt_token-2.0.0.tar.gz
Algorithm Hash digest
SHA256 9cf638e48ebee32b72a74a21aae13169a3732cf83583b4ea997a4ea237d75815
MD5 5a1518030c4c82769ea6ae49a1b4e619
BLAKE2b-256 37870f62a5704474e68b50008670a13b2b23e6192e68d7995282b238104bdb70

See more details on using hashes here.

File details

Details for the file scg_jwt_token-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: scg_jwt_token-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for scg_jwt_token-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3065c787ed5c3406d54e97635376a2734e6752ded6e3a7963541c4f68e2e4ba2
MD5 5afb21f9e81701a5532fe5edd92ee38e
BLAKE2b-256 cbd6b2cf747219e523be97b6198a90ef0eb211dcc8f7d0a33704567b12da1cbc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page