Sécurité (Fast API)

La sécurité dans FastAPI consiste à mettre en place un ensemble de mécanismes et bonnes pratiques pour protéger une API contre les attaques, l’accès non autorisé et les fuites de données.

FastAPI intègre nativement plusieurs outils de sécurité, notamment pour la gestion de l’authentification et de l’autorisation, ce qui facilite la création d’API sécurisées dès le départ.

Cela inclut :


Comment ça fonctionne dans FastAPI

Authentification et autorisation

Protection contre les attaques courantes

Sécurisation des communications

Gestion des erreurs et des logs


Exemple conceptuel


Bonnes pratiques


Pourquoi c’est important


En résumé

Fonctions :

  • Sécurité avec Fast API

    Exemple de code :

    from fastapi import FastAPI, Depends, HTTPException, status
    from fastapi.security import HTTPBasic, HTTPBasicCredentials
    import secrets
    
    app = FastAPI()
    security = HTTPBasic()
    
    # Utilisateurs autorisés (nom d'utilisateur: mot de passe)
    users_db = {
        "alice": "wonderland",
        "bob": "builder"
    }
    
    # Fonction pour vérifier les identifiants
    def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
        correct_password = users_db.get(credentials.username)
        if not correct_password or not secrets.compare_digest(credentials.password, correct_password):
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Nom d'utilisateur ou mot de passe incorrect",
                headers={"WWW-Authenticate": "Basic"},
            )
        return credentials.username
    
    # Route sécurisée
    @app.get("/secure-data")
    def read_secure_data(username: str = Depends(get_current_user)):
        return {"message": f"Bonjour {username}, vous avez accès aux données sécurisées !"}

    Explication du code :

    from fastapi import FastAPI, Depends, HTTPException, status importe FastAPI pour créer l’application, Depends pour gérer les dépendances (ici l’authentification), HTTPException pour lever des erreurs HTTP et status pour utiliser des codes de statut standardisés.

    from fastapi.security import HTTPBasic, HTTPBasicCredentials importe HTTPBasic pour l’authentification basique HTTP et HTTPBasicCredentials pour représenter les identifiants fournis par l’utilisateur.

    import secrets importe le module secrets pour comparer les mots de passe de façon sécurisée et éviter les attaques par timing.

    Créer l’application FastAPI

    app = FastAPI() crée une instance de l’application FastAPI.
    security = HTTPBasic() initialise l’authentification basique pour l’utiliser comme dépendance.

    Définir la base d’utilisateurs

    users_db = {"alice": "wonderland", "bob": "builder"} crée un dictionnaire simulant une base de données d’utilisateurs avec leurs mots de passe.

    Vérification des identifiants

    def get_current_user(credentials: HTTPBasicCredentials = Depends(security)): définit une fonction qui sera utilisée comme dépendance pour sécuriser les routes.
    credentials contient le nom d’utilisateur et le mot de passe envoyés par l’utilisateur.

    correct_password = users_db.get(credentials.username) récupère le mot de passe associé à l’utilisateur.
    if not correct_password or not secrets.compare_digest(credentials.password, correct_password): vérifie que le mot de passe est correct de manière sécurisée.
    raise HTTPException(...) lève une erreur HTTP 401 si les identifiants sont incorrects et ajoute l’en-tête WWW-Authenticate pour indiquer qu’une authentification est requise.

    return credentials.username retourne le nom d’utilisateur si l’authentification est réussie.

    Route sécurisée

    @app.get("/secure-data") définit une route GET sécurisée.
    username: str = Depends(get_current_user) indique que la route dépend de la fonction d’authentification ; seuls les utilisateurs authentifiés y accèdent.
    return {"message": f"Bonjour {username}, vous avez accès aux données sécurisées !"} renvoie un message personnalisé à l’utilisateur authentifié.