sanic-jwt

JWT authentication, refresh tokens, and scope-based permissions for the Sanic async web framework.

Library
PyPI
v1.8.0
246stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
43/100Fair
Development Activity0
Maintenance20
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture72
Code Quality78
Innovation68
Learning Curve80

Sanic JWT is an authentication add-on for the Sanic web framework that wires up JSON Web Token login, verification, and refresh endpoints without requiring the developer to hand-roll the plumbing. A single Initialize(app, authenticate=...) call registers a Blueprint of auth endpoints, wraps configuration in a dedicated Configuration class, and exposes protected and scoped decorators for guarding views and Class-Based Views alike.

Beyond the defaults, it is built to be overridden: authentication logic, refresh-token storage, scope resolution, and payload extension are all pluggable hook points via subclassing Authentication, so teams can swap in their own user store or database lookups instead of being boxed into a specific ORM or auth backend.

What You Get

  • An Initialize class that registers authenticate/verify/refresh/retrieve_user endpoints as a Sanic Blueprint with one call
  • protected and scoped decorators to guard both function-based views and Class-Based Views
  • A subclassable Authentication class for plugging in custom user lookup, refresh-token storage, and scope resolution
  • Cookie-based and split-cookie token delivery alongside standard Authorization-header tokens
  • Configurable claims (iss, aud, nbf) and support for HS256 as well as RSA/EC algorithms via the cryptography extra
  • A Claim API for registering custom, application-specific JWT claims

Common Use Cases

  • Adding login/logout and token-refresh endpoints to a Sanic API without writing JWT boilerplate by hand
  • Gating specific routes or entire Blueprints behind authentication with the protected decorator
  • Implementing role- or permission-based access control on endpoints using scoped
  • Issuing tokens via HttpOnly cookies for browser clients instead of exposing them to JavaScript
  • Extending the JWT payload with custom claims (tenant ID, permissions, etc.) for downstream services to consume

Under The Hood

Architecture The library is organized around an Initialize class (sanic_jwt/initialization.py) that walks a table of _EndpointMapping named tuples to register AuthenticateEndpoint, RetrieveUserEndpoint, VerifyEndpoint, and RefreshEndpoint as a Sanic Blueprint, and a parallel table of _Handler entries that map optional hooks (store_refresh_token, add_scopes_to_payload, retrieve_user_secret, etc.) to specific exceptions when a developer forgets to implement one. Cross-cutting behavior — checking a request for a valid token before a view runs — is implemented in decorators.py via an instant_config context manager that stashes per-request configuration overrides into a module-level cache (cache.py) for the duration of the call and clears it afterward, which lets protected/scoped wrap both plain async view functions and HTTPMethodView subclasses with the same code path.

Tech Stack Python 3.7+ targeting the Sanic async framework, with PyJWT (pyjwt>=2.1.0,<3.0.0) doing the actual token encode/decode and an optional cryptography dependency for RSA/EC-signed tokens. The test suite runs on pytest with pytest-asyncio and sanic_testing, freezegun for time-dependent token-expiry tests, and tox drives a matrix across Python 3.7-3.9 plus a dedicated check environment for flake8, black, isort, and mypy; CI is GitHub Actions (python-package.yml) with a separate python-publish.yml for PyPI releases.

Code Quality The repository ships an extensive test suite — 48 test files under tests/ covering endpoints, decorators, cookies, custom claims, blueprint composition, and cryptography-backed algorithms — alongside .coveragerc for coverage tracking and a check tox environment enforcing flake8, black (79-char lines), isort, and mypy. Error paths are explicit: unimplemented optional hooks raise dedicated exception classes (e.g. RefreshTokenNotImplemented) rather than failing silently. Development activity has slowed substantially — the health scan flags the project as inactive with its last commit in October 2024 — so quality here reflects a project that was well-tested and disciplined during active development rather than one seeing ongoing maintenance.

API Design Getting started is a three-step story the README leads with directly: install, Initialize(app, authenticate=my_authenticate), then hit /auth. Extension points are consistent — override methods on Authentication for anything non-default (refresh storage, scopes, extra payload claims) rather than juggling scattered callback parameters. The one design wrinkle is the request-scoped cache module used to thread per-call configuration through decorators; it is cleared immediately after each call and is not itself a source of cross-request bugs, but it is a less conventional pattern than passing context explicitly, and newcomers extending the library have to understand it to follow the control flow.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search