All-in-one Python authentication toolkit: password validation, password hashing, email validation, JWT handling, rate limiting, and signup/signin orchestration.
Project description
python-auth-toolkit
An all-in-one, highly secure, and configurable Python authentication toolkit. It provides robust password strength validation, secure password hashing (Bcrypt & Argon2), email validation/normalization, JWT handling, sliding window rate limiting, and sign-in/sign-up orchestrators.
Features
- Password Validator: Fully customizable complexity rules (length, casing, digits, special characters, and common password blocklist).
- Password Hasher: Secure password hashing supporting Bcrypt and Argon2id with timing-safe verification and re-hashing checks.
- Email Validator: RFC 5322 compliant syntax validation, unicode NFC normalization, disposable domain blocking, and optional DNS/MX deliverability checks.
- JWT Handler: Stateless HS256/RS256 JSON Web Token generation and validation, access/refresh token helpers, none-algorithm defense, and token blacklisting support.
- Sliding Window Rate Limiter: Thread-safe in-memory sliding window rate limiter with a
@limiter.limitdecorator supporting custom rate-limiting keys. - Signup & Signin Managers: High-level orchestration layers to coordinate validation, hashing, rate limiting, token generation, and re-hash detection during sign-up and sign-in.
Installation
Install using pip:
pip install python-auth-toolkit
For development (including test runner and coverage dependencies):
pip install "python-auth-toolkit[dev]"
# Or with uv:
uv pip install -e ".[dev]"
Quick Start
1. Signup & Signin Orchestration
from python_auth_toolkit.signup import SignupManager
from python_auth_toolkit.signin import SigninManager
from python_auth_toolkit.jwt_handler import JWTHandler
# Initialize JWT Handler
jwt_handler = JWTHandler(secret_key="your-super-secret-key-change-me")
# 1. Sign up Flow
signup_mgr = SignupManager(jwt_handler=jwt_handler)
signup_result = signup_mgr.signup("user@example.com", "P@ssw0rd123!")
print(signup_result.email) # Normalized email
print(signup_result.hashed_password) # Hashed password (ready for DB)
print(signup_result.verification_token) # JWT verification token
# Verify Email Verification Token
email = signup_mgr.verify_email_token(signup_result.verification_token)
print(email) # user@example.com
# 2. Sign in Flow (with automatic Rate Limiting & Re-hash checking)
signin_mgr = SigninManager(jwt_handler=jwt_handler)
signin_result = signin_mgr.signin(
rate_limit_key="login:user@example.com",
password="P@ssw0rd123!",
hashed_password=signup_result.hashed_password,
payload={"sub": signup_result.email}
)
if signin_result.success:
print(signin_result.access_token)
print(signin_result.refresh_token)
# If the default hash parameters were upgraded:
if signin_result.needs_rehash:
db.update_user_password(signup_result.email, signin_result.new_hash)
2. Email Validation & Normalization
from python_auth_toolkit.email_validator import EmailValidator
# Reject disposable emails and add extra domains to blocklist
validator = EmailValidator(block_disposable=True, additional_blocked_domains={"temp-inbox.xyz"})
result = validator.validate_format("user@mailinator.com")
print(result.is_valid) # False (mailinator.com is disposable)
normalized = validator.normalize(" User@Example.COM ")
print(normalized) # User@example.com
3. JWT Handler & Blacklist
from python_auth_toolkit.jwt_handler import JWTHandler, InMemoryTokenBlacklist
blacklist = InMemoryTokenBlacklist()
handler = JWTHandler(secret_key="my-secret-key", blacklist=blacklist)
# Generate access and refresh tokens
payload = {"sub": "user_id_123"}
access_token = handler.generate_access_token(payload)
# Verify
decoded = handler.verify_token(access_token)
print(decoded["token_type"]) # "access"
# Revoke a token
blacklist.blacklist(decoded["jti"], expires_at=decoded["exp"])
# Subsequent verification fails: Raises InvalidTokenError
handler.verify_token(access_token)
4. Sliding Window Rate Limiting
from python_auth_toolkit.rate_limiter import SlidingWindowRateLimiter
from python_auth_toolkit.exceptions import RateLimitExceededError
limiter = SlidingWindowRateLimiter()
# Use as a decorator: Limit function to 5 calls per 60 seconds
@limiter.limit(limit=5, window=60)
def login_attempt(username):
print(f"Login attempt for {username}")
# Or check programmatically
allowed, info = limiter.check_and_record("ip:127.0.0.1", limit=10, window=60)
if not allowed:
print(f"Too many requests. Retry after {info['reset_after']:.1f}s")
Configuration Options
PasswordValidator Parameters
min_length(int, default: 8): Minimum length required.max_length(int, default: 128): Maximum length allowed.required_uppercase(bool, default: True): Require at least one uppercase letter.required_lowercase(bool, default: True): Require at least one lowercase letter.required_digits(bool, default: True): Require at least one digit.required_special(bool, default: True): Require at least one special character.block_common_passwords(bool, default: True): Reject passwords present in the common passwords list.
PasswordHasher Parameters
algorithm(str, default:'bcrypt'): Choose between'bcrypt'or'argon2'.rounds(int, default: 12): Cost factor rounds for Bcrypt.time_cost(int, default: 3): Time cost for Argon2.memory_cost(int, default: 65536): Memory cost in KiB for Argon2.parallelism(int, default: 4): Parallelism factor threads for Argon2.
JWTHandler Parameters
secret_key(str, default:None): Key used to sign HS256 tokens.private_key(str/bytes, default:None): RSA private key (PEM format) for signing RS256 tokens.public_key(str/bytes, default:None): RSA public key (PEM format) for verifying RS256 tokens.default_algorithm(str, default:'HS256'): Default JWT algorithm (HS256orRS256).access_token_expiry(int, default: 900): Access token lifetime in seconds (15 mins).refresh_token_expiry(int, default: 604800): Refresh token lifetime in seconds (7 days).blacklist(TokenBlacklist, default:None): A blacklist instance conforming toTokenBlacklistprotocol.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file python_auth_toolkit-0.2.0.tar.gz.
File metadata
- Download URL: python_auth_toolkit-0.2.0.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a3937c2593eb9e9b9eade84b02a9570a005fd4e08adb53e504227bfc71c533c
|
|
| MD5 |
5c6430b28b35609f88ab8bd73338a508
|
|
| BLAKE2b-256 |
0406d2e50364ae0e20b5b5cdc0a1cc868cda138ec25611cb64678b64860f5915
|
File details
Details for the file python_auth_toolkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: python_auth_toolkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 19.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
291081409b2c67ae572e55e90c3f3636a76c0a9628ca39d24e95a82f16bbbc4b
|
|
| MD5 |
e6a79df1e4eaae55097805f47100ba0f
|
|
| BLAKE2b-256 |
11f5d02ba1729b1ebdcc75a313c600bc534505934f9b9325548899c8c6d66b5d
|