Exploration sur la connexion avec son adresse email

Ce que l’on veut

Les utilisateurs ne sont pas toujours très au fait du nom de domaine de leur Cozy, ils ont plutôt l’habitude d’utiliser un login ou une adresse email comme identifiant. Nous souhaiterions leur proposer de pouvoir se connecter depuis cozy.io avec leur adresse email pour les instances en mycozy.cloud.

Les contraintes

  • On veut respecter les mécanismes actuels liées aux connexions : 2FA, envoi d’un email pour les connexions depuis un nouveau device, etc.
  • On ne veut pas dévoiler à quel cozy correspond une adresse email donnée
  • On veut conserver notre niveau de sécurité (jeton anti-CSRF sur le login notamment)
  • Cozy.io est un site statique
  • La nuagerie ne peut pas interroger directement les bases de données de la stack (couchdb et redis)

Approche possible n°1

Comme Cozy.io est un site statique, on ne peut pas gérer la logique d’authentification dessus. Dans cette approche, on va passer par la nuagerie. Sur la nuagerie, on demande adresse email (pour identifier l’instance cozy) et le mot de passe. Le mot de passe sert à deux choses : d’une part, différencier si plusieurs instances cozy sont rattachées à une même adresse email et, d’autre part, vérifier que la personne est bien le propriétaire de l’instance Cozy (et pas juste quelqu’un qui voudrait savoir si telle adresse email a un cozy).

La nuagerie ne peut pas faire une redirection directement vers la stack (c’est du CSRF et ça demanderait donc de désactiver des protections). La nuagerie ne peut pas non plus essayer de se connecter en HTTPS sur la stack à la place de l’utilisateur (ça va envoyer un email d’alerte à l’utilisateur + la nuagerie ne peut pas forcer une session sur l’instance cozy). Il faudrait donc faire passer ça via un autre canal : la nuagerie peut lancer une commande cozy-stack auth [domain] avec le mot de passe. Si le mot de passe est correct, la commande renvoie un token temporaire et la nuagerie renvoie l’utilisateur vers la page de login de cette instance avec ce token en query-string.

La stack va alors détecter le token en question et considérer que le mot de passe est rempli. C’est une requête de type GET, donc pas d’anti-CSRF. Le token est à usage unique et avec une durée de vie très courte. Ensuite, la stack suit le processus classique comme si le mot de passe avait été saisi : vérification du second facteur si le 2FA est activé, envoi d’un email si la connexion se fait depuis un nouveau device, création de la session, redirection vers l’application par défaut.

Difficultés
La nuagerie doit pouvoir exécuter des commandes sur la stack et obtenir un résultat pendant la durée d’exécution d’une requête http entrante. Et c’est le backend qui reçoit la requête http entrante, il devrait passer normalement par l’API qui ferait elle-même appel aux workers pour lancer une commande cozy-stack. À voir si on s’autorise quelques raccourcis ici.


Approche possible n°2

Comme Cozy.io est un site statique, on ne peut pas gérer la logique d’authentification dessus. Dans cette approche, on va passer par une page globale sur la stack. Sur cette page, on demande adresse email (pour identifier l’instance cozy) et le mot de passe. Le mot de passe sert à deux choses : d’une part, différencier si plusieurs instances cozy sont rattachées à une même adresse email et, d’autre part, vérifier que la personne est bien le propriétaire de l’instance Cozy (et pas juste quelqu’un qui voudrait savoir si telle adresse email a un cozy).

Ça ne semble pas être une bonne idée que la page globale dépose directement les cookies d’authentification : elle serait obligée de le faire sur mycozy.cloud, ce qui risque de poser des problèmes quand l’utilisateur va aller sur d’autres instances Cozy (partages par lien) et si on veut proposer des noms de domaine personnalisés. Sur la soumission du formulaire de login, la stack va chercher l’instance associée à l’adresse email (il faudrait mettre en place une base de données Couch globale à toutes les instances pour ça) et vérifier si le mot de passe correspond. Si le mot de passe est correct, la stack crée un token temporaire et renvoie l’utilisateur vers la page de login de cette instance avec ce token en query-string.

La stack va alors détecter le token en question et considérer que le mot de passe est rempli. C’est une requête de type GET, donc pas d’anti-CSRF. Le token est à usage unique et avec une durée de vie très courte. Ensuite, la stack suit le processus classique comme si le mot de passe avait été saisi : vérification du second facteur si le 2FA est activé, envoi d’un email si la connexion se fait depuis un nouveau device, création de la session, redirection vers l’application par défaut.