jpadilla / pyjwt

JSON Web Token implementation in Python
https://pyjwt.readthedocs.io
MIT License
5.17k stars 690 forks source link

Support swapping out the cache backend for JWKClient #981

Closed rabbit-aaron closed 2 weeks ago

rabbit-aaron commented 2 months ago

Great project!

I'm using it with my Django project, where it runs multiple containers with scaling. I have a redis server shared between these instances.

I would like to cache JWKs in redis. I could provide a PR if people are interested.

I'd propose the following:

from typing import Protocol
from .jwk_set_cache import JWKSetCache

class JWKSetCacheProtocol(Protocol):
    def put(self, jwk_set: PyJWKSet) -> None: ...
        ...

    def get(self) -> Optional[PyJWKSet]:
        ...

    def is_expired(self) -> bool:
        ...

class PyJWKClient:
    def __init__(
        self,
        uri: str,
        cache_keys: bool = False,
        max_cached_keys: int = 16,
        cache_jwk_set: bool = True,
        lifespan: int = 300,
        headers: Optional[Dict[str, Any]] = None,
        timeout: int = 30,
        ssl_context: Optional[SSLContext] = None,
        jwk_set_cache: Optional[JWKSetCacheProtocol] = None,
    ):
            if headers is None:
            headers = {}
        self.uri = uri
        self.jwk_set_cache: Optional[JWKSetCache] = None
        self.headers = headers
        self.timeout = timeout
        self.ssl_context = ssl_context

        if jwk_set_cache:
            self.jwk_set_cache = jwk_set_cache

        elif cache_jwk_set:
            # Init jwt set cache with default or given lifespan.
            # Default lifespan is 300 seconds (5 minutes).
            if lifespan <= 0:
                raise PyJWKClientError(
                    f'Lifespan must be greater than 0, the input is "{lifespan}"'
                )
            self.jwk_set_cache = JWKSetCache(lifespan)
        else:
            self.jwk_set_cache = None

        if cache_keys:
            # Cache signing keys
            # Ignore mypy (https://github.com/python/mypy/issues/2427)
            self.get_signing_key = lru_cache(maxsize=max_cached_keys)(self.get_signing_key)  # type: ignore
github-actions[bot] commented 3 weeks ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days