Streamlit Authentication : Guide complet 2025
Streamlit Authentication : Guide complet 2025
L'authentification est essentielle pour sécuriser vos applications Streamlit professionnelles. Que vous créiez un dashboard interne, une app SaaS ou un outil d'entreprise, vous devez contrôler qui accède à vos données.
Depuis Streamlit 1.42.0, l'authentification est devenue beaucoup plus simple grâce aux nouvelles fonctions natives st.login(), st.logout(), et st.user. Fini les librairies tierces complexes !
Dans ce guide, je vais vous montrer toutes les méthodes d'authentification pour Streamlit en 2025, de la plus simple à la plus avancée.
Pourquoi l'authentification est cruciale
Après avoir créé plus de 50 applications Streamlit pour des clients (banques, scale-ups, agences), je peux vous dire que l'authentification est la première question qui revient systématiquement.
Les risques sans authentification
Sans authentification, vos apps Streamlit sont :
- ✅ Accessibles publiquement : N'importe qui avec l'URL peut y accéder
- ✅ Impossibles à auditer : Vous ne savez pas qui fait quoi
- ✅ Non conformes RGPD : Pas de traçabilité des accès aux données personnelles
- ✅ Vulnérables : Exposition de données sensibles
Les bénéfices de l'authentification
Avec une authentification correcte :
- ✅ Contrôle d'accès : Seuls les utilisateurs autorisés peuvent se connecter
- ✅ Personnalisation : Contenu adapté à chaque utilisateur
- ✅ Traçabilité : Logs des accès et actions
- ✅ Conformité : Respect des normes de sécurité (RGPD, SOC2, ISO 27001)
Méthode 1 : Authentification native avec st.login() (Recommandée)
Depuis Streamlit 1.42.0, la méthode officielle pour l'authentification est st.login(). Cette fonction intègre nativement OpenID Connect (OIDC) pour s'authentifier via Google, Microsoft, Okta, Auth0, etc.
Avantages de st.login()
- ✅ Méthode officielle : Supportée et maintenue par Streamlit
- ✅ Sécurisée : OAuth 2.0 + OIDC (standards de l'industrie)
- ✅ Simple : 3 fonctions seulement (
st.login(),st.logout(),st.user) - ✅ Multi-providers : Google, Microsoft, Okta, Auth0, etc.
- ✅ Pas de base de données : Pas besoin de stocker les mots de passe
Installation
pip install streamlit[auth]
Cette commande installe Streamlit avec Authlib>=1.3.2, la librairie nécessaire pour OIDC.
Configuration avec Google (exemple complet)
Étape 1 : Créer une application OAuth sur Google Cloud
- Allez sur Google Cloud Console
- Créez un nouveau projet ou sélectionnez un projet existant
- Activez l'API "Google+ API"
- Allez dans APIs & Services > Credentials
- Cliquez sur Create Credentials > OAuth 2.0 Client ID
- Choisissez Web application
- Configurez les Authorized redirect URIs :
http://localhost:8501/oauth2callback (pour développement) https://votre-app.streamlit.app/oauth2callback (pour production) - Récupérez votre Client ID et Client Secret
Étape 2 : Configurer secrets.toml
Créez le fichier .streamlit/secrets.toml :
[auth]
# URL de redirection après authentification
redirect_uri = "http://localhost:8501/oauth2callback"
# Secret pour signer les cookies (générez-en un aléatoire !)
cookie_secret = "votre_secret_aleatoire_tres_long_et_complexe"
# Credentials Google OAuth
client_id = "votre_client_id.apps.googleusercontent.com"
client_secret = "votre_client_secret"
# URL des métadonnées du serveur OIDC
server_metadata_url = "https://accounts.google.com/.well-known/openid-configuration"
⚠️ IMPORTANT : Générez un cookie_secret fort et aléatoire :
import secrets
print(secrets.token_urlsafe(32))
# Exemple : 'kX9vR3mN2pL7wQ5tY8hJ1fG4dS6aZ0cV'
Étape 3 : Implémenter l'authentification
Voici l'implémentation minimale :
import streamlit as st
# Configuration de la page
st.set_page_config(
page_title="App Sécurisée",
page_icon="🔐",
layout="wide"
)
# Vérifier si l'utilisateur est connecté
if not st.user.is_logged_in:
st.title("🔐 Authentification requise")
st.write("Connectez-vous pour accéder à l'application.")
if st.button("Se connecter avec Google", type="primary"):
st.login()
else:
# L'utilisateur est connecté
st.title("🎉 Bienvenue !")
# Afficher les informations utilisateur
col1, col2 = st.columns([3, 1])
with col1:
st.write(f"**Nom** : {st.user.name}")
st.write(f"**Email** : {st.user.email}")
if hasattr(st.user, 'picture'):
st.image(st.user.picture, width=100)
with col2:
if st.button("Se déconnecter"):
st.logout()
st.markdown("---")
# Contenu de l'application
st.subheader("📊 Contenu protégé")
st.write("Seuls les utilisateurs authentifiés peuvent voir ce contenu.")
# Exemple : afficher toutes les informations de l'utilisateur
with st.expander("🔍 Informations complètes de l'utilisateur"):
st.json(st.user.to_dict())
Configuration avec Microsoft Azure AD
Pour Microsoft Entra ID (anciennement Azure AD) :
[auth]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "votre_secret_aleatoire"
client_id = "votre_azure_client_id"
client_secret = "votre_azure_client_secret"
# Pour Azure AD
server_metadata_url = "https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration"
Remplacez {tenant_id} par votre ID de tenant Azure.
Informations disponibles avec Microsoft :
st.user.email # Email de l'utilisateur
st.user.name # Nom complet
st.user.preferred_username # Nom d'utilisateur préféré
st.user.oid # Object ID (GUID unique)
st.user.tid # Tenant ID
Configuration avec Okta
[auth]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "votre_secret_aleatoire"
client_id = "votre_okta_client_id"
client_secret = "votre_okta_client_secret"
# Remplacez {your-okta-domain} par votre domaine Okta
server_metadata_url = "https://{your-okta-domain}/.well-known/openid-configuration"
Configuration avec Auth0
[auth]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "votre_secret_aleatoire"
client_id = "votre_auth0_client_id"
client_secret = "votre_auth0_client_secret"
# Remplacez {your-auth0-domain} par votre domaine Auth0
server_metadata_url = "https://{your-auth0-domain}/.well-known/openid-configuration"
Utiliser plusieurs providers
Vous pouvez configurer plusieurs providers simultanément :
# Provider par défaut (Google)
[auth]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "votre_secret_aleatoire"
client_id = "google_client_id"
client_secret = "google_client_secret"
server_metadata_url = "https://accounts.google.com/.well-known/openid-configuration"
# Provider Microsoft
[auth.microsoft]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "votre_secret_aleatoire"
client_id = "microsoft_client_id"
client_secret = "microsoft_client_secret"
server_metadata_url = "https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration"
# Provider Okta
[auth.okta]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "votre_secret_aleatoire"
client_id = "okta_client_id"
client_secret = "okta_client_secret"
server_metadata_url = "https://{okta-domain}/.well-known/openid-configuration"
Dans votre code :
import streamlit as st
if not st.user.is_logged_in:
st.title("🔐 Choisissez votre méthode de connexion")
col1, col2, col3 = st.columns(3)
with col1:
if st.button("🔵 Google", use_container_width=True):
st.login() # Provider par défaut
with col2:
if st.button("🟦 Microsoft", use_container_width=True):
st.login(provider="microsoft")
with col3:
if st.button("🟧 Okta", use_container_width=True):
st.login(provider="okta")
else:
st.write(f"Connecté en tant que {st.user.email}")
if st.button("Se déconnecter"):
st.logout()
Méthode 2 : Authentification simple (mot de passe)
Pour des cas d'usage simples (prototypes, démos internes), vous pouvez utiliser une authentification par mot de passe stockée dans secrets.toml.
Implémentation basique
import streamlit as st
import hashlib
# Fonction pour hasher les mots de passe
def hash_password(password):
return hashlib.sha256(password.encode()).hexdigest()
# Vérifier l'authentification
def check_password():
"""Retourne True si l'utilisateur est authentifié"""
# Initialiser session state
if "authenticated" not in st.session_state:
st.session_state.authenticated = False
# Si déjà authentifié
if st.session_state.authenticated:
return True
# Formulaire de connexion
st.title("🔐 Connexion")
username = st.text_input("Nom d'utilisateur")
password = st.text_input("Mot de passe", type="password")
if st.button("Se connecter", type="primary"):
# Récupérer les credentials depuis secrets.toml
users = st.secrets.get("users", {})
if username in users:
stored_hash = users[username]["password_hash"]
input_hash = hash_password(password)
if stored_hash == input_hash:
st.session_state.authenticated = True
st.session_state.username = username
st.session_state.role = users[username].get("role", "user")
st.rerun()
else:
st.error("❌ Mot de passe incorrect")
else:
st.error("❌ Utilisateur inconnu")
return False
# Utilisation
if check_password():
st.title(f"👋 Bienvenue {st.session_state.username}")
if st.button("Se déconnecter"):
st.session_state.authenticated = False
st.rerun()
# Votre application ici
st.write("Contenu protégé")
else:
st.stop()
Configuration dans secrets.toml
[users.admin]
password_hash = "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" # "admin"
role = "admin"
[users.john]
password_hash = "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3" # "123"
role = "user"
Pour générer les hash :
import hashlib
print(hashlib.sha256("votre_mot_de_passe".encode()).hexdigest())
⚠️ Limitations :
- Les mots de passe sont en clair dans secrets.toml (même hashés, c'est risqué)
- Pas de gestion des sessions multi-utilisateurs
- Pas de "mot de passe oublié"
- Ne convient PAS pour des apps publiques
Méthode 3 : Authentification avec base de données
Pour des applications professionnelles, utilisez une base de données pour stocker les utilisateurs.
Exemple avec PostgreSQL
import streamlit as st
import psycopg2
import hashlib
import bcrypt
from datetime import datetime
# Connexion à la base de données
@st.cache_resource
def get_db_connection():
return psycopg2.connect(
host=st.secrets["db"]["host"],
database=st.secrets["db"]["database"],
user=st.secrets["db"]["user"],
password=st.secrets["db"]["password"]
)
# Vérifier les credentials
def verify_credentials(email, password):
"""Vérifie email et mot de passe dans la base de données"""
conn = get_db_connection()
cur = conn.cursor()
cur.execute(
"SELECT id, email, password_hash, role, name FROM users WHERE email = %s",
(email,)
)
user = cur.fetchone()
cur.close()
if user and bcrypt.checkpw(password.encode(), user[2].encode()):
return {
"id": user[0],
"email": user[1],
"role": user[3],
"name": user[4]
}
return None
# Log de connexion
def log_login(user_id, success):
"""Enregistre une tentative de connexion"""
conn = get_db_connection()
cur = conn.cursor()
cur.execute(
"""
INSERT INTO login_logs (user_id, timestamp, success, ip_address)
VALUES (%s, %s, %s, %s)
""",
(user_id, datetime.now(), success, st.context.headers.get("X-Forwarded-For"))
)
conn.commit()
cur.close()
# Interface de connexion
def login_page():
st.title("🔐 Connexion")
with st.form("login_form"):
email = st.text_input("Email")
password = st.text_input("Mot de passe", type="password")
submitted = st.form_submit_button("Se connecter", type="primary")
if submitted:
user = verify_credentials(email, password)
if user:
st.session_state.user = user
log_login(user["id"], True)
st.success("✅ Connexion réussie !")
st.rerun()
else:
log_login(None, False)
st.error("❌ Email ou mot de passe incorrect")
# Vérification de l'authentification
def require_auth():
"""Force l'authentification"""
if "user" not in st.session_state:
login_page()
st.stop()
# Utilisation
require_auth()
# Sidebar avec infos utilisateur
with st.sidebar:
st.write(f"👤 **{st.session_state.user['name']}**")
st.write(f"📧 {st.session_state.user['email']}")
st.write(f"🔑 Role: {st.session_state.user['role']}")
if st.button("Se déconnecter"):
del st.session_state.user
st.rerun()
# Application
st.title("📊 Application sécurisée")
st.write("Contenu accessible uniquement aux utilisateurs authentifiés")
Schema SQL pour la base de données
-- Table des utilisateurs
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP
);
-- Table des logs de connexion
CREATE TABLE login_logs (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
timestamp TIMESTAMP NOT NULL,
success BOOLEAN NOT NULL,
ip_address VARCHAR(45)
);
-- Index pour optimiser les requêtes
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_login_logs_user ON login_logs(user_id);
CREATE INDEX idx_login_logs_timestamp ON login_logs(timestamp);
Script pour créer un utilisateur
import bcrypt
import psycopg2
def create_user(email, password, name, role="user"):
# Hasher le mot de passe
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
# Insérer dans la DB
conn = psycopg2.connect(...)
cur = conn.cursor()
cur.execute(
"""
INSERT INTO users (email, password_hash, name, role)
VALUES (%s, %s, %s, %s)
""",
(email, password_hash, name, role)
)
conn.commit()
cur.close()
conn.close()
# Créer un admin
create_user("admin@example.com", "secure_password", "Admin User", "admin")
Gestion des rôles et permissions
Une fois l'authentification en place, vous pouvez implémenter un système de rôles (RBAC - Role-Based Access Control).
Décorateur pour contrôler l'accès
from functools import wraps
import streamlit as st
def require_role(*allowed_roles):
"""Décorateur pour restreindre l'accès par rôle"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if "user" not in st.session_state:
st.error("❌ Vous devez être connecté")
st.stop()
user_role = st.session_state.user.get("role")
if user_role not in allowed_roles:
st.error(f"❌ Accès refusé. Rôle requis : {', '.join(allowed_roles)}")
st.stop()
return func(*args, **kwargs)
return wrapper
return decorator
# Utilisation
@require_role("admin", "manager")
def admin_dashboard():
st.title("🔧 Dashboard Admin")
st.write("Seuls les admins et managers peuvent voir cette page")
# Fonctionnalités admin
users_count = get_users_count()
st.metric("Utilisateurs", users_count)
@require_role("admin")
def manage_users():
st.title("👥 Gestion des utilisateurs")
st.write("Seuls les admins peuvent gérer les utilisateurs")
# CRUD des utilisateurs
# ...
# Dans votre app
if st.session_state.user["role"] == "admin":
admin_dashboard()
manage_users()
else:
st.info("Vous n'avez pas accès aux fonctionnalités d'administration")
Navigation basée sur les rôles
import streamlit as st
# Définir les pages accessibles par rôle
PAGES_BY_ROLE = {
"user": ["🏠 Accueil", "📊 Dashboard", "⚙️ Paramètres"],
"manager": ["🏠 Accueil", "📊 Dashboard", "👥 Équipe", "📈 Rapports", "⚙️ Paramètres"],
"admin": ["🏠 Accueil", "📊 Dashboard", "👥 Équipe", "📈 Rapports", "🔧 Admin", "⚙️ Paramètres"]
}
# Récupérer les pages accessibles pour l'utilisateur
user_role = st.session_state.user["role"]
available_pages = PAGES_BY_ROLE.get(user_role, PAGES_BY_ROLE["user"])
# Sidebar avec navigation
with st.sidebar:
st.write(f"👤 {st.session_state.user['name']}")
st.write(f"🔑 {user_role.upper()}")
st.markdown("---")
selected_page = st.radio("Navigation", available_pages)
st.markdown("---")
if st.button("Se déconnecter"):
del st.session_state.user
st.rerun()
# Afficher la page sélectionnée
if selected_page == "🏠 Accueil":
home_page()
elif selected_page == "📊 Dashboard":
dashboard_page()
elif selected_page == "👥 Équipe":
team_page()
elif selected_page == "📈 Rapports":
reports_page()
elif selected_page == "🔧 Admin":
admin_page()
elif selected_page == "⚙️ Paramètres":
settings_page()
Bonnes pratiques de sécurité
1. Utiliser HTTPS en production
⚠️ CRITIQUE : Toujours utiliser HTTPS en production pour protéger les cookies de session.
Sur Streamlit Cloud, HTTPS est activé par défaut. Sur votre propre serveur, configurez un reverse proxy (nginx, Caddy) avec certificat SSL.
2. Expiration des sessions
Avec st.login(), les cookies expirent après 30 jours d'inactivité. Vous pouvez implémenter une expiration personnalisée :
from datetime import datetime, timedelta
# Vérifier l'expiration du token
if st.user.is_logged_in:
exp = st.user.get("exp") # Timestamp d'expiration
if exp and datetime.fromtimestamp(exp) < datetime.now():
st.warning("⚠️ Votre session a expiré")
st.logout()
st.stop()
3. Protection contre les attaques brute-force
Limitez le nombre de tentatives de connexion :
import time
from datetime import datetime, timedelta
# Initialiser le compteur
if "login_attempts" not in st.session_state:
st.session_state.login_attempts = 0
st.session_state.last_attempt = None
def login_with_rate_limit(email, password):
# Vérifier le rate limiting
if st.session_state.login_attempts >= 5:
if st.session_state.last_attempt:
time_elapsed = (datetime.now() - st.session_state.last_attempt).seconds
if time_elapsed < 300: # 5 minutes
wait_time = 300 - time_elapsed
st.error(f"❌ Trop de tentatives. Réessayez dans {wait_time // 60} minutes.")
return False
else:
# Reset après 5 minutes
st.session_state.login_attempts = 0
# Tenter la connexion
user = verify_credentials(email, password)
if user:
st.session_state.login_attempts = 0
st.session_state.user = user
return True
else:
st.session_state.login_attempts += 1
st.session_state.last_attempt = datetime.now()
return False
4. Ne jamais stocker de secrets en clair
❌ Mauvais :
# secrets.toml
password = "mon_mot_de_passe" # EN CLAIR !
✅ Bon :
# secrets.toml
password_hash = "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
5. Logs d'audit
Tracez toutes les actions importantes :
def log_action(user_id, action, details=None):
"""Enregistre une action utilisateur"""
conn = get_db_connection()
cur = conn.cursor()
cur.execute(
"""
INSERT INTO audit_logs (user_id, action, details, timestamp, ip_address)
VALUES (%s, %s, %s, %s, %s)
""",
(user_id, action, details, datetime.now(), get_client_ip())
)
conn.commit()
cur.close()
# Utilisation
log_action(st.session_state.user["id"], "view_sensitive_data", "Customer database")
log_action(st.session_state.user["id"], "export_data", "Q4 sales report")
Erreurs courantes à éviter
1. Oublier st.stop() après redirection
❌ Mauvais :
if not st.user.is_logged_in:
st.login()
# Le code continue à s'exécuter !
st.write("Contenu protégé") # Visible même non connecté !
✅ Bon :
if not st.user.is_logged_in:
st.login()
st.stop() # Arrête l'exécution
st.write("Contenu protégé")
2. Ne pas sécuriser les secrets en production
Sur Streamlit Cloud, utilisez les Secrets dans le dashboard :
- Allez dans votre app sur Streamlit Cloud
- Settings > Secrets
- Collez votre configuration
secrets.toml
Ne commitez JAMAIS secrets.toml dans Git !
3. Utiliser session_state sans vérification
❌ Mauvais :
st.write(f"Hello {st.session_state.user['name']}") # KeyError si non connecté !
✅ Bon :
if "user" in st.session_state:
st.write(f"Hello {st.session_state.user['name']}")
else:
st.write("Veuillez vous connecter")
4. Ne pas valider les inputs utilisateur
❌ Mauvais :
email = st.text_input("Email")
# Pas de validation !
verify_credentials(email, password)
✅ Bon :
import re
email = st.text_input("Email")
if email and not re.match(r"[^@]+@[^@]+\.[^@]+", email):
st.error("❌ Format d'email invalide")
st.stop()
verify_credentials(email, password)
Déploiement sécurisé
Sur Streamlit Cloud
-
Configurer les secrets :
- Dashboard > Settings > Secrets
- Coller votre configuration OIDC
-
Configurer le redirect_uri :
redirect_uri = "https://votre-app.streamlit.app/oauth2callback" -
Activer HTTPS (activé par défaut sur Streamlit Cloud)
Sur votre propre serveur
Utilisez Docker + nginx :
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
Configuration nginx :
server {
listen 80;
server_name votre-domaine.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name votre-domaine.com;
ssl_certificate /etc/letsencrypt/live/votre-domaine.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/votre-domaine.com/privkey.pem;
location / {
proxy_pass http://localhost:8501;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Cas d'usage réels
Voici 3 implémentations que j'ai réalisées pour des clients :
1. Dashboard interne (Startup SaaS)
- Authentification : Google OAuth via
st.login() - Utilisateurs : 15 employés
- Rôles : admin, sales, support
- Impact : Réduction de 80% du temps de configuration (vs solution custom)
2. Plateforme d'analyse (Banque)
- Authentification : Microsoft Azure AD
- Utilisateurs : 200+ analystes
- Rôles : viewer, analyst, admin
- Compliance : Logs d'audit complets, expiration de session à 30 min
- Impact : Conformité SOC2 + RGPD
3. App de reporting client (Agence)
- Authentification : Base de données PostgreSQL
- Utilisateurs : 50+ clients externes
- Rôles : client, agency_user, admin
- Fonctionnalités : Chaque client voit uniquement ses données
- Impact : +40% d'engagement client (vs PDF statiques)
Ressources complémentaires
Documentation officielle
Mes formations
Pour maîtriser Streamlit de A à Z, découvrez ma formation complète :
👉 Streamlit Unleashed - 20h de contenu, 50+ exercices pratiques, section complète sur la sécurité et l'authentification
Outils gratuits
- Roast My Streamlit : Audit gratuit de votre app (inclut analyse de sécurité)
- Streamlit Cheatsheet : Aide-mémoire PDF gratuit
Librairies utiles
- Authlib : Librairie OAuth/OIDC utilisée par
st.login() - bcrypt : Hashing sécurisé de mots de passe
- PyJWT : Validation de tokens JWT
Conclusion
L'authentification sur Streamlit est devenue beaucoup plus simple en 2025 grâce à st.login(). Voici mes recommandations :
Pour des apps internes (< 50 utilisateurs) :
✅ Utilisez st.login() avec Google ou Microsoft OAuth
Pour des apps professionnelles (50-500 utilisateurs) :
✅ Utilisez st.login() avec un provider d'entreprise (Okta, Azure AD)
✅ Ajoutez un système de rôles (RBAC)
✅ Implémentez des logs d'audit
Pour des apps SaaS (500+ utilisateurs) : ✅ Base de données dédiée avec bcrypt ✅ Système de rôles avancé ✅ Logs d'audit complets ✅ Rate limiting sur les connexions ✅ Sessions avec expiration courte
Checklist de sécurité :
- ✅ HTTPS obligatoire en production
- ✅ Secrets stockés dans
.streamlit/secrets.toml(jamais dans le code) - ✅ Mots de passe hashés avec bcrypt (jamais en clair)
- ✅ Rate limiting sur les tentatives de connexion
- ✅ Logs d'audit pour toutes les actions critiques
- ✅ Validation des inputs utilisateur
- ✅ Expiration automatique des sessions
L'authentification n'est plus un obstacle pour créer des applications Streamlit professionnelles et sécurisées. Avec les bonnes pratiques de ce guide, vous pouvez déployer des apps conformes aux standards de l'industrie.
Prochaines étapes :
- Choisissez votre méthode d'authentification
- Configurez votre provider OAuth (ou votre DB)
- Implémentez
st.login()dans votre app - Testez en local puis déployez sur Streamlit Cloud
Des questions sur l'authentification Streamlit ? Contactez-moi sur LinkedIn ou par email à gael@mes-formations-data.fr.
Cet article fait partie de ma série complète sur Streamlit. Pour aller plus loin :

📚 Approfondir avec mon livre
"Business Intelligence avec Python" - Le guide complet pour maîtriser l'analyse de données
Voir sur Amazon →