PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

The User is dead 9   Recently updated !

mardi 14 juillet 2015 à 14:27

L’authentification de mémé (enfin, mémé…) n’a plus de sens, et pourtant, on continue de la montrer en exemple dans tous les tutos :

Boom, on vérifie le mot de passe (avec un peu de chance sur une version sainement hachée), on identifie l’utilisateur, et c’est plié.

C’est simple, c’est beau, ça marche.

Mais ça ne représente pas du tout la réalité.

Une des plus grosses erreurs de design de frameworks comme Django est justement la classe User.

En soit, la classe User n’est pas un problème, mais son omniprésence dans toutes les couches du framework et sa promotion au rang d’unité de référence dans les apps tierces parties ont gardé la vision de l’authentification très monolithique.

C’est que le Web n’a plus du tout la forme qu’il avait il y a 10 ans, et aujourd’hui, vous pouvez vous connecter via un service (facebook, twitter, github…), utiliser une authentification à double facteur (sms, email, yubikey…) ou avoir un compte unique qui unifie plusieurs fournisseurs (ah, le fameux compte Google qui fait gmail, youtube, calendar, play, saucisseland…).

Les gens ont plusieurs identités, plusieurs comptes, plusieurs modes d’authentification, plusieurs points d’entrées. Ce modèle ne marche plus :

USER <-- Profile 

Si vous créez un service aujourd'hui et que vous souhaitez prendre en compte cette réalité, le schéma en base de données va plutôt ressembler à un truc du genre :

                      +-------+
                      |Session|
                      +----+--+
                           |
                           |
                           |
                           |
+-----------+         +----v---+         +--------+
|  Identity | <-------+ Account| <-------+Profile |
+-----------+         +--------+         +--------+
                 +------^   ^--------+
                 |                   |
                 |                   |
                 |                   |
                 |                   |
         +-------+-----+      +------+----+
         | Credential  |      |  Service  |
         +-------------+      +-----------+

Et encore, je n'ai pas mis les permissions, les devices, les comptes multi-utilisateurs, la vérification des comptes (lien email, sms, etc), les niveaux d'offre commerciale... Ca rend le truc vraiment compliqué.

Ce qui est important ici, c'est que la notion de compte devient centrale, mais que seule l'identité est unique. Une identité peut avoir plusieurs comptes. Et un compte peut être chez votre service ou un service externe. Et l'authentification peut très bien avoir lieu ailleurs : ldap, OAuth, Mozilla Personna, Open ID...

Si votre utilisateur a un compte chez Facebook et un compte chez vous, les deux sont des comptes, avec leurs profils, reliés à la même identité, servant à vous donner des informations, permettant de se loguer... Et vous devez garder une trace de tout ça. Le fait que l'API d'un service tape sur votre serveur et l'autre non n'a en fait aucune importance pour l'utilisateur, qui utilise tout ça comme un gros blob comme si internet était un tout.

La nouvelle génération ne fait pas la différence avec un site Web et un app, ne sait pas ce qu'est une URL ou un cookie et ne veut pas rentrer trop de mots de passe, mais veut par contre utiliser 5000 services.

Ainsi on voit que les archis basées sur des microservices (hello crossbar :)) commencent à avoir la côte, faisant abstraction de la notion de "ceci est mon app, ceci est ton app" dans la structure de son projet. Bien entendu, la distinction est importante d'un point de vue humain, mais du point de vue du workflow d'authentification, non.

Par contre, forcément, ça fait beaucoup plus qu'une table User et une table Profile en base de données, et c'est pourquoi toutes les apps pluggables des frameworks actuellement ont leurs propres structures bizarres, incompatibles et torturées pour faire tenir toute cette logique. Parce qu'on code sur des frameworks qui vivent encore dans les années 2000, qui passent à votre vue un objet User en paramètre avec ses attributs username et email.

Mais ce que vous avez en face de vous, ce n'est pas un utilisateur.

C'est une session d'utilisation.

D'un service (le votre). Liée à un compte. Qui peut-être (surement) possède un profil avec un username.

Cette session s'est initiée par une authentification avec une méthode parmi 100 auprès d'un service également, lié à un compte, avec un profil. Peut-être le même service que celui qui est utilisé, peut-être pas.

Et cette authentification a pu être demandée par un utilisateur, ou encore un autre service, ou un logiciel client complètement automatiquement. Souvenez-vous : la session n'a peut-être aucun humain derrière.

Ce qui est en face de vous n'est pas un utilisateur. L'utilisateur est mort il y a des années.

Error happened! 0 - count(): Argument #1 ($value) must be of type Countable|array, null given In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:428 http://ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/?The-User-is-dead-Recently-updated #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #1 /var/www/ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/index.php(1): require_once('...') #2 {main}