From 5a6859263bdb4db1386b244fd7fe5710d0379223 Mon Sep 17 00:00:00 2001 From: Esteban Maya Cadavid Date: Thu, 16 May 2024 15:49:06 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Update=20basic=20JWT=20auth=20do?= =?UTF-8?q?cumentation=20to=20use=20PyJWT=20and=20remove=20pyhon-jose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/tutorial/security/oauth2-jwt.md | 59 ++++++++++---------- docs_src/security/tutorial004.py | 5 +- docs_src/security/tutorial004_an.py | 5 +- docs_src/security/tutorial004_an_py310.py | 5 +- docs_src/security/tutorial004_an_py39.py | 5 +- docs_src/security/tutorial004_py310.py | 5 +- 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/docs/en/docs/tutorial/security/oauth2-jwt.md b/docs/en/docs/tutorial/security/oauth2-jwt.md index b02d00c3f..5c69c0f99 100644 --- a/docs/en/docs/tutorial/security/oauth2-jwt.md +++ b/docs/en/docs/tutorial/security/oauth2-jwt.md @@ -26,28 +26,29 @@ After a week, the token will be expired and the user will not be authorized and If you want to play with JWT tokens and see how they work, check https://jwt.io. -## Install `python-jose` +## Install `PyJWT` -We need to install `python-jose` to generate and verify the JWT tokens in Python: +We need to install `PyJWT` to generate and verify the JWT tokens in Python:
```console -$ pip install "python-jose[cryptography]" +$ pip install pyjwt ---> 100% ```
-Python-jose requires a cryptographic backend as an extra. +PyJWT The default package includes types and common cryptography algorithms like `HS256`, `HS512`, `PS*`, `RS*`, among others -Here we are using the recommended one: pyca/cryptography. +If you are planning to use digital signature algorithms like RSA or ECDSA, you should install the cryptography library dependency `pyjwt[crypto]`. +For more info please visit PyJWT Cryptographic Dependencies (Optional). -!!! tip - This tutorial previously used PyJWT. +!!! note + This tutorial previously used python-jose. - But it was updated to use Python-jose instead as it provides all the features from PyJWT plus some extras that you might need later when building integrations with other tools. + But it was deprecated to use PyJWT instead as python-jose seems to be abandoned and several security issues(CVE) has been reported using this outdated library. ## Password hashing @@ -111,19 +112,19 @@ And another one to authenticate and return a user. === "Python 3.10+" - ```Python hl_lines="7 48 55-56 59-60 69-75" + ```Python hl_lines="8 49 56-57 60-61 70-76" {!> ../../../docs_src/security/tutorial004_an_py310.py!} ``` === "Python 3.9+" - ```Python hl_lines="7 48 55-56 59-60 69-75" + ```Python hl_lines="8 49 56-57 60-61 70-76" {!> ../../../docs_src/security/tutorial004_an_py39.py!} ``` === "Python 3.8+" - ```Python hl_lines="7 49 56-57 60-61 70-76" + ```Python hl_lines="8 50 57-58 61-62 71-77" {!> ../../../docs_src/security/tutorial004_an.py!} ``` @@ -132,7 +133,7 @@ And another one to authenticate and return a user. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="6 47 54-55 58-59 68-74" + ```Python hl_lines="7 48 55-56 59-60 69-75" {!> ../../../docs_src/security/tutorial004_py310.py!} ``` @@ -141,7 +142,7 @@ And another one to authenticate and return a user. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="7 48 55-56 59-60 69-75" + ```Python hl_lines="8 49 56-57 60-61 70-76" {!> ../../../docs_src/security/tutorial004.py!} ``` @@ -178,19 +179,19 @@ Create a utility function to generate a new access token. === "Python 3.10+" - ```Python hl_lines="6 12-14 28-30 78-86" + ```Python hl_lines="4 7 13-15 29-31 79-87" {!> ../../../docs_src/security/tutorial004_an_py310.py!} ``` === "Python 3.9+" - ```Python hl_lines="6 12-14 28-30 78-86" + ```Python hl_lines="4 7 13-15 29-31 79-87" {!> ../../../docs_src/security/tutorial004_an_py39.py!} ``` === "Python 3.8+" - ```Python hl_lines="6 13-15 29-31 79-87" + ```Python hl_lines="4 7 14-16 30-32 80-88" {!> ../../../docs_src/security/tutorial004_an.py!} ``` @@ -199,7 +200,7 @@ Create a utility function to generate a new access token. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="5 11-13 27-29 77-85" + ```Python hl_lines="3 6 12-14 28-30 78-86" {!> ../../../docs_src/security/tutorial004_py310.py!} ``` @@ -208,7 +209,7 @@ Create a utility function to generate a new access token. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="6 12-14 28-30 78-86" + ```Python hl_lines="4 7 13-15 29-31 79-87" {!> ../../../docs_src/security/tutorial004.py!} ``` @@ -222,19 +223,19 @@ If the token is invalid, return an HTTP error right away. === "Python 3.10+" - ```Python hl_lines="89-106" + ```Python hl_lines="90-107" {!> ../../../docs_src/security/tutorial004_an_py310.py!} ``` === "Python 3.9+" - ```Python hl_lines="89-106" + ```Python hl_lines="90-107" {!> ../../../docs_src/security/tutorial004_an_py39.py!} ``` === "Python 3.8+" - ```Python hl_lines="90-107" + ```Python hl_lines="91-108" {!> ../../../docs_src/security/tutorial004_an.py!} ``` @@ -243,7 +244,7 @@ If the token is invalid, return an HTTP error right away. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="88-105" + ```Python hl_lines="89-106" {!> ../../../docs_src/security/tutorial004_py310.py!} ``` @@ -252,7 +253,7 @@ If the token is invalid, return an HTTP error right away. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="89-106" + ```Python hl_lines="90-107" {!> ../../../docs_src/security/tutorial004.py!} ``` @@ -264,19 +265,19 @@ Create a real JWT access token and return it. === "Python 3.10+" - ```Python hl_lines="117-132" + ```Python hl_lines="118-133" {!> ../../../docs_src/security/tutorial004_an_py310.py!} ``` === "Python 3.9+" - ```Python hl_lines="117-132" + ```Python hl_lines="118-133" {!> ../../../docs_src/security/tutorial004_an_py39.py!} ``` === "Python 3.8+" - ```Python hl_lines="118-133" + ```Python hl_lines="119-134" {!> ../../../docs_src/security/tutorial004_an.py!} ``` @@ -285,7 +286,7 @@ Create a real JWT access token and return it. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="114-129" + ```Python hl_lines="115-130" {!> ../../../docs_src/security/tutorial004_py310.py!} ``` @@ -294,7 +295,7 @@ Create a real JWT access token and return it. !!! tip Prefer to use the `Annotated` version if possible. - ```Python hl_lines="115-130" + ```Python hl_lines="116-131" {!> ../../../docs_src/security/tutorial004.py!} ``` @@ -384,7 +385,7 @@ Many packages that simplify it a lot have to make many compromises with the data It gives you all the flexibility to choose the ones that fit your project the best. -And you can use directly many well maintained and widely used packages like `passlib` and `python-jose`, because **FastAPI** doesn't require any complex mechanisms to integrate external packages. +And you can use directly many well maintained and widely used packages like `passlib` and `PyJWT`, because **FastAPI** doesn't require any complex mechanisms to integrate external packages. But it provides you the tools to simplify the process as much as possible without compromising flexibility, robustness, or security. diff --git a/docs_src/security/tutorial004.py b/docs_src/security/tutorial004.py index d0fbaa572..91d161b8a 100644 --- a/docs_src/security/tutorial004.py +++ b/docs_src/security/tutorial004.py @@ -1,9 +1,10 @@ from datetime import datetime, timedelta, timezone from typing import Union +import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jose import JWTError, jwt +from jwt.exceptions import InvalidTokenError from passlib.context import CryptContext from pydantic import BaseModel @@ -98,7 +99,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)): if username is None: raise credentials_exception token_data = TokenData(username=username) - except JWTError: + except InvalidTokenError: raise credentials_exception user = get_user(fake_users_db, username=token_data.username) if user is None: diff --git a/docs_src/security/tutorial004_an.py b/docs_src/security/tutorial004_an.py index eebd36d64..df50754af 100644 --- a/docs_src/security/tutorial004_an.py +++ b/docs_src/security/tutorial004_an.py @@ -1,9 +1,10 @@ from datetime import datetime, timedelta, timezone from typing import Union +import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jose import JWTError, jwt +from jwt.exceptions import InvalidTokenError from passlib.context import CryptContext from pydantic import BaseModel from typing_extensions import Annotated @@ -99,7 +100,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]): if username is None: raise credentials_exception token_data = TokenData(username=username) - except JWTError: + except InvalidTokenError: raise credentials_exception user = get_user(fake_users_db, username=token_data.username) if user is None: diff --git a/docs_src/security/tutorial004_an_py310.py b/docs_src/security/tutorial004_an_py310.py index 4e50ada7c..eff54ef01 100644 --- a/docs_src/security/tutorial004_an_py310.py +++ b/docs_src/security/tutorial004_an_py310.py @@ -1,9 +1,10 @@ from datetime import datetime, timedelta, timezone from typing import Annotated +import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jose import JWTError, jwt +from jwt.exceptions import InvalidTokenError from passlib.context import CryptContext from pydantic import BaseModel @@ -98,7 +99,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]): if username is None: raise credentials_exception token_data = TokenData(username=username) - except JWTError: + except InvalidTokenError: raise credentials_exception user = get_user(fake_users_db, username=token_data.username) if user is None: diff --git a/docs_src/security/tutorial004_an_py39.py b/docs_src/security/tutorial004_an_py39.py index eb49aaa67..0455b500c 100644 --- a/docs_src/security/tutorial004_an_py39.py +++ b/docs_src/security/tutorial004_an_py39.py @@ -1,9 +1,10 @@ from datetime import datetime, timedelta, timezone from typing import Annotated, Union +import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jose import JWTError, jwt +from jwt.exceptions import InvalidTokenError from passlib.context import CryptContext from pydantic import BaseModel @@ -98,7 +99,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]): if username is None: raise credentials_exception token_data = TokenData(username=username) - except JWTError: + except InvalidTokenError: raise credentials_exception user = get_user(fake_users_db, username=token_data.username) if user is None: diff --git a/docs_src/security/tutorial004_py310.py b/docs_src/security/tutorial004_py310.py index 5a905783d..78bee22a3 100644 --- a/docs_src/security/tutorial004_py310.py +++ b/docs_src/security/tutorial004_py310.py @@ -1,8 +1,9 @@ from datetime import datetime, timedelta, timezone +import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jose import JWTError, jwt +from jwt.exceptions import InvalidTokenError from passlib.context import CryptContext from pydantic import BaseModel @@ -97,7 +98,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)): if username is None: raise credentials_exception token_data = TokenData(username=username) - except JWTError: + except InvalidTokenError: raise credentials_exception user = get_user(fake_users_db, username=token_data.username) if user is None: