Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🐍
Intermediaire 25 min FastAPI

Securiser une application FastAPI

Pourquoi Securiser une application FastAPI ?

Dans le monde numérique, la sécurité est un préoccupation majeure pour les développeurs. Un système non sécurisé peut être facilement exploité par des attaquants malveillants qui peuvent accéder à vos données sensibles, modifier ou même détruire votre application. Avec FastAPI, une de ces frameworks Python puissants et modernes, la sécurité est également une priorité.

Un cas d'usage concret : imaginez que vous développiez une API de gestion des utilisateurs pour une entreprise. Si cette API n'est pas sécurisée, un pirate informatique pourrait voler les informations des utilisateurs, ce qui pourrait entraîner des dommages financiers et réputationnels.

Prerequis

  • Connaissances Necessaires :

    • Python (version recommandée : 3.7+)
    • FastAPI (version recommandée : 0.68.1)
    • Uvicorn ou Hypercorn pour l'exécution de l'application
    • SQLAlchemy (pour les opérations de base de données)
  • Outils à Installer :

    pip install fastapi uvicorn sqlalchemy databases[postgresql]
    

Concepts Fondamentaux

1. Authentication et Authorization

Authentication est le processus par lequel une application vérifie l'identité d'un utilisateur. Authorization, en revanche, détermine les actions que cet utilisateur peut effectuer dans l'application.

## Importations nécessaires pour FastAPI et OAuth2
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

2. Middleware

Les middleware sont des fonctions qui s'exécutent avant ou après l'traitement de la requête par le routeur FastAPI.

## Exemple de middleware pour vérifier les autorisations
from fastapi import Request, HTTPException

async def get_current_user(request: Request):
    auth_header = request.headers.get("Authorization")
    if not auth_header:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing Authorization Header")
    # Vérifiez le token ici et renvoyez l'utilisateur
    return {"user": "admin"}

3. Hashing des Mot de Passe

Les mots de passe doivent toujours être hashés pour stocker les informations de connexion en toute sécurité.

## Importation pour le hashing des mots de passe
from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
    return pwd_context.hash(password)

Mise en Pratique : Projet Fil Rouge

Étape 1: Création de l'Application FastAPI

Créons un nouveau projet FastAPI.

mkdir fastapi-security-demo
cd fastapi-security-demo
uvicorn main:app --reload

Créez le fichier main.py :

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

app = FastAPI()

## Middleware pour vérifier les autorisations
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    response = await call_next(request)
    return response

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

## Exemple de modèle utilisateur
fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW",  # Hasse du mot de passe "secret"
    }
}

## Fonction pour obtenir les informations de l'utilisateur
async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")
    return {"user": user["username"]}

## Route pour obtenir le token d'authentification
@app.post("/token", response_model={"access_token": str})
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = fake_users_db.get(form_data.username)
    if not user or not verify_password(form_data.password, user["hashed_password"]):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token = form_data.username  # Dans un scénario réel, utiliser une bibliothèque pour générer des tokens sécurisés
    return {"access_token": access_token}

## Route protégée
@app.get("/protected")
async def protected_route(current_user: dict = Depends(get_current_user)):
    return {"message": f"Hello {current_user['user']}", "status_code": 200}

Étape 2: Exécution de l'Application

Exécutez votre application FastAPI :

uvicorn main:app --reload

Accédez à http://127.0.0.1:8000/docs pour voir les routes générées par Swagger UI.

Étape 3: Test de la Authentification

Testez la route /token pour obtenir un token d'authentification :

curl -X POST "http://127.0.0.1:8000/token" -d "username=johndoe&password=secret"

Vous devriez recevoir un token comme réponse.

Étape 4: Accès à la Route Protégée

Utilisez le token pour accéder à la route protégée :

curl -X GET "http://127.0.0.1:8000/protected" -H "Authorization: Bearer your_access_token"

Erreurs Frequentes et Debugging

1. Mauvaise Vérification du Token d'Authentification

Code Incorrect :

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")
    return {"user": user["username"]}

Code Correct :

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")
    return {"user": user["username"]}

2. Erreur de Vérification du Mot de Passe

Code Incorrect :

def verify_password(plain_password, hashed_password):
    if plain_password == hashed_password:
        return True
    return False

Code Correct :

from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

3. Erreur de Middleware

Code Incorrect :

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    response = await call_next(request)
    return response

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")
    return {"user": user["username"]}

Code Correct :

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    response = await call_next(request)
    return response

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")
    return {"user": user["username"]}

Pour Aller Plus loin

1. Authentification avec OAuth2 et JWT

Pour une authentification plus sécurisée, utiliser OAuth2 avec des tokens JWT.

Documentation FastAPI - OAuth2 and JWT

2. Base de Données Sécurisés

Utiliser SQLAlchemy pour les opérations de base de données et PostgreSQL pour la gestion sécurisée des données.

Documentation SQLAlchemy

3. Gestion des Sessions Utilisateurs

Gérer les sessions utilisateurs avec FastAPI et OAuth2.

Documentation FastAPI - User Authentication with OAuth2 and JWT

Défi Pratique

Créez une application FastAPI qui utilise OAuth2 et JWT pour l'authentification. Implémentez des routes protégées pour accéder aux données sensibles.

Besoin d'aide sur FastAPI ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment configurer les autorisations d'accès dans une application FastAPI ?
Pour configurer les autorisations d'accès dans une application FastAPI, vous pouvez utiliser des décorateurs comme `@ Depends()` avec des fonctions de gestionnaire d'autorisation personnalisées. Ces fonctions vérifient si l'utilisateur a les droits nécessaires avant d'exécuter la fonction associée à l'endpoint.
Quelles sont les meilleures pratiques pour sécuriser les données sensibles dans une application FastAPI ?
Pour protéger les données sensibles, utilisez des variables d'environnement pour stocker les informations de connexion à la base de données et les clés API. Appliquez également des hashages forts pour les mots de passe et configurez le transport sécurisé en utilisant HTTPS.
Comment gérer efficacement les exceptions dans une application FastAPI pour éviter les informations sensibles d'être révélées aux utilisateurs ?
Pour gérer les exceptions de manière sécurisée, utilisez des blocs `try-except` autour du code qui peut échouer et renvoyez des messages d'erreur personnalisés. Assurez-vous que ces messages ne contiennent pas d'informations sensibles sur la structure internes de votre application.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.