python-jwt


Namepython-jwt JSON
Version 4.1.0 PyPI version JSON
download
home_pagehttps://github.com/davedoesdev/python-jwt
SummaryModule for generating and verifying JSON Web Tokens
upload_time2023-11-13 07:57:03
maintainer
docs_urlNone
authorDavid Halls
requires_python>=3.6
licenseMIT
keywords
VCS
bugtrack_url
requirements jwcrypto gevent pyVows pylint coverage coveralls mock
Travis-CI No Travis.
coveralls test coverage
            # python-jwt   [![Build Status](https://github.com/davedoesdev/python-jwt/actions/workflows/ci.yml/badge.svg)](https://github.com/davedoesdev/python-jwt/actions/workflows/ci.yml) [![Coverage Status](https://coveralls.io/repos/github/davedoesdev/python-jwt/badge.svg?branch=master)](https://coveralls.io/github/davedoesdev/python-jwt?branch=master) [![PyPI version](https://badge.fury.io/py/python-jwt.svg)](https://badge.fury.io/py/python-jwt)

Module for generating and verifying [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html).

***All versions of python-jwt are now DEPRECATED. I don't have the time to maintain this module.***

- **Note:** Versions 3.3.4 and later fix a [vulnerability](https://github.com/davedoesdev/python-jwt/security/advisories/GHSA-5p8v-58qm-c7fp) (CVE-2022-39227) in JSON Web Token verification which lets an attacker with a valid token re-use its signature with modified claims. CVE to follow. Please upgrade!
- **Note:** From version 2.0.1 the namespace has changed from `jwt` to `python_jwt`, in order to avoid conflict with [PyJWT](https://github.com/jpadilla/pyjwt).
- **Note:** Versions 1.0.0 and later fix a [vulnerability](https://www.timmclean.net/2015/02/25/jwt-alg-none.html) in JSON Web Token verification so please upgrade if you're using this functionality. The API has changed so you will need to update your application. [verify_jwt](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/docs/_build/html/index.html#python_jwt.verify_jwt) now requires you to specify which signature algorithms are allowed.
- Uses [jwcrypto](https://jwcrypto.readthedocs.io) to do the heavy lifting.
- Supports [__RS256__, __RS384__, __RS512__](https://tools.ietf.org/html/rfc7518#section-3.3), [__PS256__, __PS384__, __PS512__](https://tools.ietf.org/html/rfc7518#section-3.5), [__HS256__, __HS384__, __HS512__](https://tools.ietf.org/html/rfc7518#section-3.2), [__ES256__, __ES384__, __ES512__](https://tools.ietf.org/html/rfc7518#section-3.4), [__ES256K__](https://tools.ietf.org/html/draft-ietf-cose-webauthn-algorithms-05#section-3.2), [__EdDSA__](https://tools.ietf.org/html/rfc8037#section-3.1) and [__none__](http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-14#section-3.6) signature algorithms.
- Unit tests, including tests for interoperability with [jose](https://github.com/panva/jose).
- Supports Python 3.6+. **Note:** [generate_jwt](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/docs/_build/html/index.html#python_jwt.generate_jwt) returns the token as a Unicode string.

Example:

```python
import python_jwt as jwt, jwcrypto.jwk as jwk, datetime
key = jwk.JWK.generate(kty='RSA', size=2048)
payload = { 'foo': 'bar', 'wup': 90 };
token = jwt.generate_jwt(payload, key, 'PS256', datetime.timedelta(minutes=5))
header, claims = jwt.verify_jwt(token, key, ['PS256'])
for k in payload: assert claims[k] == payload[k]
```

The API is described [here](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/docs/_build/html/index.html).


## Installation

```shell
pip install python_jwt
```

## Another Example

You can read and write keys from and to [PEM-format](http://www.openssl.org/docs/crypto/pem.html) strings:

```python
import python_jwt as jwt, jwcrypto.jwk as jwk, datetime
key = jwk.JWK.generate(kty='RSA', size=2048)
priv_pem = key.export_to_pem(private_key=True, password=None)
pub_pem = key.export_to_pem()
payload = { 'foo': 'bar', 'wup': 90 };
priv_key = jwk.JWK.from_pem(priv_pem)
pub_key = jwk.JWK.from_pem(pub_pem)
token = jwt.generate_jwt(payload, priv_key, 'RS256', datetime.timedelta(minutes=5))
header, claims = jwt.verify_jwt(token, pub_key, ['RS256'])
for k in payload: assert claims[k] == payload[k]
```

## Licence

[MIT](https://raw.github.com/davedoesdev/python-jwt/master/LICENCE)

## Tests

```shell
make test
```

## Lint

```shell
make lint
```

## Code Coverage

```shell
make coverage
```

[coverage.py](http://nedbatchelder.com/code/coverage/) results are available [here](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/coverage/html/index.html).

Coveralls page is [here](https://coveralls.io/r/davedoesdev/python-jwt).

## Benchmarks

```shell
make bench
```

Here are some results on a laptop with an Intel Core i5-4300M 2.6Ghz CPU and 8Gb RAM running Ubuntu 17.04.

Generate Key|user (ns)|sys (ns)|real (ns)
:--|--:|--:|--:
RSA|103,100,000|200,000|103,341,537

Generate Token|user (ns)|sys (ns)|real (ns)
:--|--:|--:|--:
HS256|220,000|0|226,478
HS384|220,000|0|218,233
HS512|230,000|0|225,823
PS256|1,530,000|10,000|1,536,235
PS384|1,550,000|0|1,549,844
PS512|1,520,000|10,000|1,524,844
RS256|1,520,000|10,000|1,524,565
RS384|1,530,000|0|1,528,074
RS512|1,510,000|0|1,526,089

Load Key|user (ns)|sys (ns)|real (ns)
:--|--:|--:|--:
RSA|210,000|3,000|210,791

Verify Token|user (ns)|sys (ns)|real (ns)
:--|--:|--:|--:
HS256|100,000|0|101,478
HS384|100,000|10,000|103,014
HS512|110,000|0|104,323
PS256|230,000|0|231,058
PS384|240,000|0|237,551
PS512|240,000|0|232,450
RS256|230,000|0|227,737
RS384|230,000|0|230,698
RS512|230,000|0|228,624

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/davedoesdev/python-jwt",
    "name": "python-jwt",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "",
    "author": "David Halls",
    "author_email": "dave@davedoesdev.com",
    "download_url": "https://files.pythonhosted.org/packages/77/e6/583bac8fa3fbdfd36db587d053a9c4d3692b6d345400d94e278e630b8543/python_jwt-4.1.0.tar.gz",
    "platform": null,
    "description": "# python-jwt   [![Build Status](https://github.com/davedoesdev/python-jwt/actions/workflows/ci.yml/badge.svg)](https://github.com/davedoesdev/python-jwt/actions/workflows/ci.yml) [![Coverage Status](https://coveralls.io/repos/github/davedoesdev/python-jwt/badge.svg?branch=master)](https://coveralls.io/github/davedoesdev/python-jwt?branch=master) [![PyPI version](https://badge.fury.io/py/python-jwt.svg)](https://badge.fury.io/py/python-jwt)\n\nModule for generating and verifying [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html).\n\n***All versions of python-jwt are now DEPRECATED. I don't have the time to maintain this module.***\n\n- **Note:** Versions 3.3.4 and later fix a [vulnerability](https://github.com/davedoesdev/python-jwt/security/advisories/GHSA-5p8v-58qm-c7fp) (CVE-2022-39227) in JSON Web Token verification which lets an attacker with a valid token re-use its signature with modified claims. CVE to follow. Please upgrade!\n- **Note:** From version 2.0.1 the namespace has changed from `jwt` to `python_jwt`, in order to avoid conflict with [PyJWT](https://github.com/jpadilla/pyjwt).\n- **Note:** Versions 1.0.0 and later fix a [vulnerability](https://www.timmclean.net/2015/02/25/jwt-alg-none.html) in JSON Web Token verification so please upgrade if you're using this functionality. The API has changed so you will need to update your application. [verify_jwt](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/docs/_build/html/index.html#python_jwt.verify_jwt) now requires you to specify which signature algorithms are allowed.\n- Uses [jwcrypto](https://jwcrypto.readthedocs.io) to do the heavy lifting.\n- Supports [__RS256__, __RS384__, __RS512__](https://tools.ietf.org/html/rfc7518#section-3.3), [__PS256__, __PS384__, __PS512__](https://tools.ietf.org/html/rfc7518#section-3.5), [__HS256__, __HS384__, __HS512__](https://tools.ietf.org/html/rfc7518#section-3.2), [__ES256__, __ES384__, __ES512__](https://tools.ietf.org/html/rfc7518#section-3.4), [__ES256K__](https://tools.ietf.org/html/draft-ietf-cose-webauthn-algorithms-05#section-3.2), [__EdDSA__](https://tools.ietf.org/html/rfc8037#section-3.1) and [__none__](http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-14#section-3.6) signature algorithms.\n- Unit tests, including tests for interoperability with [jose](https://github.com/panva/jose).\n- Supports Python 3.6+. **Note:** [generate_jwt](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/docs/_build/html/index.html#python_jwt.generate_jwt) returns the token as a Unicode string.\n\nExample:\n\n```python\nimport python_jwt as jwt, jwcrypto.jwk as jwk, datetime\nkey = jwk.JWK.generate(kty='RSA', size=2048)\npayload = { 'foo': 'bar', 'wup': 90 };\ntoken = jwt.generate_jwt(payload, key, 'PS256', datetime.timedelta(minutes=5))\nheader, claims = jwt.verify_jwt(token, key, ['PS256'])\nfor k in payload: assert claims[k] == payload[k]\n```\n\nThe API is described [here](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/docs/_build/html/index.html).\n\n\n## Installation\n\n```shell\npip install python_jwt\n```\n\n## Another Example\n\nYou can read and write keys from and to [PEM-format](http://www.openssl.org/docs/crypto/pem.html) strings:\n\n```python\nimport python_jwt as jwt, jwcrypto.jwk as jwk, datetime\nkey = jwk.JWK.generate(kty='RSA', size=2048)\npriv_pem = key.export_to_pem(private_key=True, password=None)\npub_pem = key.export_to_pem()\npayload = { 'foo': 'bar', 'wup': 90 };\npriv_key = jwk.JWK.from_pem(priv_pem)\npub_key = jwk.JWK.from_pem(pub_pem)\ntoken = jwt.generate_jwt(payload, priv_key, 'RS256', datetime.timedelta(minutes=5))\nheader, claims = jwt.verify_jwt(token, pub_key, ['RS256'])\nfor k in payload: assert claims[k] == payload[k]\n```\n\n## Licence\n\n[MIT](https://raw.github.com/davedoesdev/python-jwt/master/LICENCE)\n\n## Tests\n\n```shell\nmake test\n```\n\n## Lint\n\n```shell\nmake lint\n```\n\n## Code Coverage\n\n```shell\nmake coverage\n```\n\n[coverage.py](http://nedbatchelder.com/code/coverage/) results are available [here](http://rawgit.davedoesdev.com/davedoesdev/python-jwt/master/coverage/html/index.html).\n\nCoveralls page is [here](https://coveralls.io/r/davedoesdev/python-jwt).\n\n## Benchmarks\n\n```shell\nmake bench\n```\n\nHere are some results on a laptop with an Intel Core i5-4300M 2.6Ghz CPU and 8Gb RAM running Ubuntu 17.04.\n\nGenerate Key|user (ns)|sys (ns)|real (ns)\n:--|--:|--:|--:\nRSA|103,100,000|200,000|103,341,537\n\nGenerate Token|user (ns)|sys (ns)|real (ns)\n:--|--:|--:|--:\nHS256|220,000|0|226,478\nHS384|220,000|0|218,233\nHS512|230,000|0|225,823\nPS256|1,530,000|10,000|1,536,235\nPS384|1,550,000|0|1,549,844\nPS512|1,520,000|10,000|1,524,844\nRS256|1,520,000|10,000|1,524,565\nRS384|1,530,000|0|1,528,074\nRS512|1,510,000|0|1,526,089\n\nLoad Key|user (ns)|sys (ns)|real (ns)\n:--|--:|--:|--:\nRSA|210,000|3,000|210,791\n\nVerify Token|user (ns)|sys (ns)|real (ns)\n:--|--:|--:|--:\nHS256|100,000|0|101,478\nHS384|100,000|10,000|103,014\nHS512|110,000|0|104,323\nPS256|230,000|0|231,058\nPS384|240,000|0|237,551\nPS512|240,000|0|232,450\nRS256|230,000|0|227,737\nRS384|230,000|0|230,698\nRS512|230,000|0|228,624\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Module for generating and verifying JSON Web Tokens",
    "version": "4.1.0",
    "project_urls": {
        "Homepage": "https://github.com/davedoesdev/python-jwt"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "18b84c404573791c4ead576d9d98f2749d41f3c61ce293cf07f7960232ec9b74",
                "md5": "e2415e1e1b97f27ffa9739cce8ccd2c4",
                "sha256": "1f4d44b6b9176375489c0374c71f18f27f52524e689174e11dd39a801170c91b"
            },
            "downloads": -1,
            "filename": "python_jwt-4.1.0-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e2415e1e1b97f27ffa9739cce8ccd2c4",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=3.6",
            "size": 7066,
            "upload_time": "2023-11-13T07:57:01",
            "upload_time_iso_8601": "2023-11-13T07:57:01.564389Z",
            "url": "https://files.pythonhosted.org/packages/18/b8/4c404573791c4ead576d9d98f2749d41f3c61ce293cf07f7960232ec9b74/python_jwt-4.1.0-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "77e6583bac8fa3fbdfd36db587d053a9c4d3692b6d345400d94e278e630b8543",
                "md5": "f4c9d7d15d0b95233a9009ccf9664133",
                "sha256": "f89af071d9bda4741bc80754bd1cfce73e434a2cbb7855086d8604a10bd3fdc5"
            },
            "downloads": -1,
            "filename": "python_jwt-4.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f4c9d7d15d0b95233a9009ccf9664133",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 291210,
            "upload_time": "2023-11-13T07:57:03",
            "upload_time_iso_8601": "2023-11-13T07:57:03.765711Z",
            "url": "https://files.pythonhosted.org/packages/77/e6/583bac8fa3fbdfd36db587d053a9c4d3692b6d345400d94e278e630b8543/python_jwt-4.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-13 07:57:03",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "davedoesdev",
    "github_project": "python-jwt",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [
        {
            "name": "jwcrypto",
            "specs": [
                [
                    ">=",
                    "1.4.2"
                ]
            ]
        },
        {
            "name": "gevent",
            "specs": [
                [
                    ">=",
                    "1.2.2"
                ]
            ]
        },
        {
            "name": "pyVows",
            "specs": [
                [
                    ">=",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "pylint",
            "specs": [
                [
                    ">=",
                    "1.4.4"
                ]
            ]
        },
        {
            "name": "coverage",
            "specs": [
                [
                    ">=",
                    "4.0.3"
                ]
            ]
        },
        {
            "name": "coveralls",
            "specs": [
                [
                    ">=",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "mock",
            "specs": [
                [
                    ">=",
                    "1.3.0"
                ]
            ]
        }
    ],
    "lcname": "python-jwt"
}
        
Elapsed time: 0.27894s