Authentification

Réinitialisation de mot de passe

Ce que le framework fournit

Runique intègre un système complet, prêt à l'emploi :

  • 2 routes auto-enregistrées (formulaire oubli + réinitialisation)
  • 2 formulaires fournis (ForgotPasswordForm, PasswordResetForm)
  • Génération et validation de tokens (UUID, TTL 1h, usage unique)
  • Envoi automatique de l'email si le mailer est configuré
  • Rate limiting intégré (5 requêtes / 5 min par défaut)
  • Messages i18n inclus
  • Déconnexion automatique à l'accès au formulaire de reset
  • Selon l'état du compte : lien d'activation (compte en attente), lien de réinitialisation (compte actif), email « compte bloqué » sans lien (compte désactivé) — la page répond toujours la même chose. Voir États d'un compte

Activation

RuniqueAppBuilder::new(config)
    .with_mailer_from_env()
    .with_password_reset(|pr| pr)
    .build()
    .await?

Les liens envoyés par email partent de l'URL publique du site, définie dans le builder par .with_public_url("https://monsite.com") (voir Builder).

En production, l'application refuse de démarrer sans elle : sinon le lien serait construit à partir de l'en-tête Host de la requête, qu'un attaquant choisit (Host: evil.com → le jeton de la victime part chez lui). En debug, le Host reste le repli, avec un avertissement.

Les comptes sont ceux de eihwaz_users, la table utilisateur du framework — à enrichir avec extend!{ table: "eihwaz_users", ... }.


Configuration

Toutes les options sont optionnelles — les valeurs par défaut fonctionnent sans rien changer.

.with_password_reset(|pr| pr
    .forgot_route("/mot-de-passe-oublie")       // défaut : /forgot-password
    .reset_route("/reinitialiser")               // défaut : /reset-password
    .forgot_template("auth/oubli.html")          // défaut : auth/forgot_password.html
    .reset_template("auth/reset.html")           // défaut : auth/reset_password.html
    .email_template("emails/reset.html")         // défaut : template intégré
    .success_redirect("/connexion")              // défaut : /
    .token_ttl(Duration::from_secs(1800))        // défaut : 1h (std::time::Duration)
)

Templates

Deux templates sont à créer dans templates/. Si absents, le framework utilise ses propres templates par défaut.

auth/forgot_password.html — formulaire "email oublié"

{% extends "base.html" %}
{% block content %}
<form method="post">
    {{ form.html | safe }}
    <button type="submit">Envoyer le lien</button>
</form>

{% if form.errors.email %}
    <p class="error">{{ form.errors.email }}</p>
{% endif %}
{% endblock %}

Variables disponibles dans le contexte Tera :

VariableDescription
formFormulaire avec champ email
form.errorsErreurs de validation

auth/reset_password.html — formulaire de reset

{% extends "base.html" %}
{% block content %}
<form method="post">
    {{ form.html | safe }}
    <button type="submit">Changer le mot de passe</button>
</form>

{% if form.errors.password %}
    <p class="error">{{ form.errors.password }}</p>
{% endif %}
{% endblock %}

Variables disponibles :

VariableDescription
formFormulaire avec champs password + confirm (token et email sont en hidden)
form.errorsErreurs de validation

Validations automatiques : mot de passe minimum 10 caractères, confirmation identique, token valide et non expiré.


Flux complet

1. Utilisateur clique "Mot de passe oublié"
        ↓
2. GET /forgot-password → affiche le formulaire email
        ↓
3. POST /forgot-password → email soumis
   - Si l'email existe : génère un token (1h), envoie un email avec le lien
   - Si l'email est inconnu : même réponse (sécurité — ne révèle pas les comptes existants)
        ↓
4. Utilisateur clique le lien reçu par email
        ↓
5. GET /reset-password/{token}/{email_chiffré} → affiche le formulaire de reset
   - Token invalide ou expiré → erreur
        ↓
6. POST /reset-password/{token}/{email_chiffré}
   - Valide le formulaire (mot de passe min 10 chars, confirmation)
   - Consomme le token (usage unique)
   - Met à jour le mot de passe en DB
   - Redirige vers success_redirect (défaut : /)

Sessions actives après reset : une fois le nouveau mot de passe enregistré, toutes les sessions du compte sont fermées, sur tous les appareils — une session volée comprise. L'utilisateur se reconnecte avec le nouveau mot de passe. Les autres comptes ne sont pas touchés. Seuls les stores de Runique sont concernés : un store branché avec with_session_store() (Redis…) ne peut pas être parcouru par utilisateur — voir Révocation des sessions.


Intégration admin

Si l'admin est activé avec .user_resource(), le panel peut envoyer des liens de reset directement depuis la fiche utilisateur.

Le lien part de l'URL publique (.with_public_url()) et de la route du reset configurée (reset_route, /reset-password par défaut) : rien à régler côté admin. Sans mailer configuré, le lien s'affiche dans un flash message.

Template email admin (optionnel, sinon template par défaut) :

  • templates/admin/reset_password_email.html
  • templates/admin/user_created_email.html

Variables disponibles dans ces templates : username, email, reset_url.


Sans mailer configuré

Le mailer est optionnel. Si absent :

  • En développement : le lien de reset s'affiche dans un flash message dans l'admin
  • Côté formulaire oublié : le message de succès s'affiche mais aucun email n'est envoyé

Pour tester en dev sans serveur SMTP : EMAIL_BACKEND=console imprime l'email dans le terminal.


← Authentification | Mailer →