{"id":15070030,"url":"https://github.com/glocktober/jwtencoder","last_synced_at":"2026-01-03T10:08:57.880Z","repository":{"id":62573522,"uuid":"402203989","full_name":"Glocktober/JwtEncoder","owner":"Glocktober","description":"A JwtEncoder class using PyJWT","archived":false,"fork":false,"pushed_at":"2021-09-21T21:22:10.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T19:48:32.414Z","etag":null,"topics":["jwt","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Glocktober.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-01T21:10:11.000Z","updated_at":"2022-12-16T01:41:05.000Z","dependencies_parsed_at":"2022-11-03T18:40:32.764Z","dependency_job_id":null,"html_url":"https://github.com/Glocktober/JwtEncoder","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glocktober%2FJwtEncoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glocktober%2FJwtEncoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glocktober%2FJwtEncoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glocktober%2FJwtEncoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Glocktober","download_url":"https://codeload.github.com/Glocktober/JwtEncoder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243838060,"owners_count":20355977,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jwt","python3"],"created_at":"2024-09-25T01:46:35.974Z","updated_at":"2026-01-03T10:08:57.848Z","avatar_url":"https://github.com/Glocktober.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## JwtEncoder\n\n**JwtEncoder** provides abstracted JWT token generation (using [PyJWT](https://pypi.org/project/PyJWT/) and validation with a dictionary configuration ment to simply creation and deployment.\n\n### Installation\n\n```bash\n# pip install JwtEncoder\n```\n### Usage\n\u003e Token creator:\n```python\nfrom JwtEncoder import JwtEncoder\nfrom config import jwt_config\n\njenc = JwtEncoder(jwt_config)\n\ntok = jenc.encode({'hello': 'world', 'aud': 'xyz'})\n```\n\u003e Token consumer:\n```python\nfrom JwtEncoder import JwtEncoder\nfrom config import jwt_config\n\njenc = JwtEncoder(jwt_config)\n\npayload = jenc.decode(tok, audience='xyz')\n\nprint(payload['hello'])  # 'world'\n\n```\n#### Signature\n```python\njenc = JwtEncoder(jwt_config=config)\n```\n**`jwt_config`** A python `dict` used to configure a JWT Authorizor.\n* The makeup of this dict is discussed below in more detail. \n* By default a symmetric key is generated and tokens are signed using the **HS256** signing algorithm.\n\n#### JwtEncoder Methods\n\n**`tok = jenc.encode(payload, **kwargs)`** \n\n* Returns a JWT token `tok` from the dict `payload` with a signature and options described in `jwt_config`.  \n* Additional options (kwargs) can be included as specified in the [PyJWT documentation](https://pyjwt.readthedocs.io/en/stable/)\n\n**`pay = jenc.decode(tok, **kwargs)`**\n\n* Validates the JWT token `tok` and returns decoded payload `pay` using the signature algorithm, signing keys, and issuer specified in `jwt_config`. \n* Additional options (kwargs) can be provided as specified in [PyJWT documentation](https://pyjwt.readthedocs.io/en/stable/)\n\n**`unverpay = jenc.decode_noverify(tok)`**\n\n* Returns contents of the payload `unverpay`, without verifying the signature or other jwt elements.\n* The token should be verified with `jenc.decode()` before any contents are used for authorization or authentication.\n\n**`hdrs = jenc.header(tok)`**\n* Returns JWT header options.\n* The tok should be validated first with `jenc.decode()`\n\n## *jwt_config* configuration details\n\n**JwtEncoder** uses the **PyJWT** module to implement both encoding and decoding of JWT's. The **`jwt_config`** python *`dict`* permits **JwtEncoder**  to support a various different JWT signing methods. These include:\n* shared key signing (symmetric key)\n* public and private key (asymmetric key)\n* providing an X509 RSA certificate (asymmetric key)\n* JWKS url (asymmetric key)\n\nThe choice determines which options and which signing algorithms are valid.\n#### shared key (symmetric key)\n\nTo use a symmetric key **`jwt_config`** is of the form:\n```python\njwt_config = {\n    'key': 'mysecretkey',\n    'alg': 'HS256'  # any valid JWT HS type\n    'iss': 'urn:myissuer',\n    'ttl': 3600 \n}\n```\n* **`key`** the value of this is the shared binary signing key, and `key` indicates this JwtEncoder will use symmetric key signing.\n* **`alg`** specifies the algorithm. For a symmentric key the default signing algorithm is **HS256**.\n\n#### public/private key (asymmetric key)\n\n**`pubkey`** and **`privkey`** (either or both) in **jwt_config*** indicates the JwtEncoder will use asymmetric keys for signing:\n```python\njwt_config = {\n    'pubkey': b'------BEGIN PUBLIC KEY....',\n    'privkey': b'------BEGIN PRIVATE KEY...',\n    'alg': 'RS256',\n    'iss': 'urn:myissuer'\n}\n```\n* **`pubkey`** and **`privkey`** are binary, PEM encoded keys. \n* Asymmetric signing can include RSA or elliptic curve key pairs (with the appropriate `alg` choice.)\n* The default algorithm (`alg`) is **RS256** unless specified otherwise.\n* If only the `pubkey` is provided the JwtEncoder can only decode tokens.\n* If only the `privkey` is provided the JwtEncoder can only encode tokens.\n\n#### X509 certificate (asymmetric key)\nA binary X509 certificate indicates the JwtEncoder will use asymmetric RSA signing keys:\n```python\njwt_config = {\n    'cert' : b`----BEGIN CERTIFICATE---....',\n    'alg': 'RS256',\n    'iss': 'urn:xyz'\n}\n```\n* `cert` provides only a public key, and hence  only token decoding - unless a `privkey` is also provided in the `jwt_config`.\n* No validation of the X509 certificate authenticity is made.\n* The default `alg` is **RS256**\n\n#### JWKS retrieval\nRetrieves JASON Web Key Sets (JWKS) signing keys from the specified URL:\n```python\njst_config = {\n    'jwks_url': 'https://.....',\n    'iss': 'api://myapi'\n}\n```\n* This retrieves JWKS keys (for example, from an OIDC provider)  The retrival specifies the algorithms used.\n* Any number of keys can be provided by the jwks_url and the decoder will use the algorithm and signing key identifier (`kid`) specified in the jwt header. \n* You can only decode tokens using the `jwks_url` method.\n\n### Additional Options\n\n**`alg`** - *algorithm*\n\n* `alg` specifies the signing algorithm used.\n* For symmetric signing the default is `HS256`; for asymmetric signing, `RS256`\n* There are various signing algorithms outlined in the JWT specifications, and in the PyJWT documentation.\n\n**`ttl`** - *time to live*\n\n* *time to live* is the length of time the tokens the JwtEncoder generates will be valid.\n* If `ttl` is not specified, 3600 Seconds is used by default.\n* The token `exp` value is set to the current epoch time + ttl; the token will also include `nbf` and `iat` set to the current time.\n* If `ttl` is explicitly set to `None`, the `iat`, `nbf`, and `exp` elements are not added to token encoding - the tokens do not expire.\n* Decoding an expired token raises an exception.\n\n**`iss`** - *issuer*\n\n* The issuer is added as `iss` to the payload for encoding tokens, and is verified when tokens are decoded.  \n* An alternate issuer can be specified by adding `iss` to the payload before calling `encode({'iss': 'xyz'})`, and can be verified by passing the kwarg `issuer` on decode (e.g. `decode(token,issuer='xyz'))`\n* decoding a token where the token `iss` doesn't match the issuer generates an exception.\n\n### Audience Validation\n\nIf a jwt has an `aud` (audience) element specified when encoded, then `audience` kwarg must be specified when decoding for the token to validate.\n```python\ntok = jenc.encode({'aud': 'db21', 'scp': ['table.write']})\n...\npay = jenc.decode(tok, audience=['db21', 'db22'])\n```\n* `audience` can be a `list`, as in the example, containing multiple options.  The token need only match one of them.\n* decoding a token without the matching audience generates an exception.\n\n### Generating Signing Keys\n\nFor reference only:\n\nGenerating Eliptic Curve key pairs using Openssl:\n```bash\n# openssl ecparam -name prime256v1 -genkey -noout -out private.pem\n# openssl ec -in private.pem -pubout -out public.pem\n```\n\nGenerating RSA key pairs using Openssl:\n```bash\n# openssl genrsa  -out rsaprivate.pem 2048\n# openssl rsa -in rsaprivate.pem -pubout -out rsapublic.pem\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglocktober%2Fjwtencoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglocktober%2Fjwtencoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglocktober%2Fjwtencoder/lists"}