Maison >développement back-end >Tutoriel Python >Une compréhension approfondie des cookies, des sessions et des jetons dans un seul article
Histoire du développement
1 Il y a bien longtemps, le Web se contentait de parcourir des documents. est en train de naviguer, en tant que serveur, il n'est pas nécessaire d'enregistrer qui a parcouru quels documents au cours d'une certaine période de temps. Chaque requête est un nouveau protocole HTTP, qui est une requête plus une réponse. Surtout, je n'ai pas besoin de me rappeler qui. je viens d'envoyer une requête HTTP. Chaque requête Les deux requêtes sont nouvelles pour moi. C’est une période très excitante.
2. Cependant, avec l'essor des applications Web interactives, telles que les sites Web d'achats en ligne, les sites Web qui nécessitent une connexion, etc., nous sommes immédiatement confrontés à un problème : pour gérer les sessions, nous devons nous rappeler qui se connecte. dans le système. Qui met les articles dans son panier, c'est-à-dire que je dois distinguer chaque personne, ce qui est un gros défi, car les requêtes HTTP sont sans état, donc la solution que j'ai trouvée est d'envoyer une session à tout le monde. ID. (identifiant de session), pour parler franchement, c'est une chaîne aléatoire. Chaque fois que vous m'envoyez une requête HTTP, envoyez-la avec elle pour que je puisse la distinguer.
3. De cette façon, tout le monde est très content, mais le serveur n'est pas content. Tout le monde n'a qu'à enregistrer son propre identifiant de session, et le serveur doit enregistrer l'identifiant de session de chacun ! S’il y a trop de serveurs d’accès, il y en aura des milliers, voire des centaines de milliers.
Cela représente une surcharge énorme pour le serveur et limite considérablement les capacités d'expansion du serveur. Par exemple, si j'utilise deux machines pour former un cluster et que Little F se connecte au système via la machine A, l'identifiant de session. sera enregistré sur la machine A, que se passera-t-il si la prochaine demande de Little F est transmise à la machine B ? La machine B n'a pas l'identifiant de session du petit F.
Parfois une petite astuce est utilisée : session sticky, ce qui signifie que la requête du petit F est toujours collée à la machine A, mais cela ne fonctionne pas. Si la machine A raccroche, il faut la transférer sur la machine A. B. .
Ensuite, nous devons copier la session. Déplacer l'identifiant de session entre les deux machines est presque épuisant.
Plus tard, quelqu'un appelé Memcached a trouvé une astuce : stocker les identifiants de session de manière centralisée en un seul endroit, et toutes les machines accéderont aux données de cette manière. Il n'est pas nécessaire de copier, mais cela augmente la possibilité d'un point de défaillance unique. Si la machine responsable de la session raccroche, tout le monde devra se reconnecter et sera probablement grondé à mort.
J'ai également essayé de mettre cette seule machine dans un cluster pour augmenter la fiabilité, mais quoi qu'il en soit, cette petite session est un lourd fardeau pour moi.
4. Alors certaines personnes se sont demandé : pourquoi devrais-je sauvegarder cette abominable session ?
Mais si ces identifiants de session ne sont pas enregistrés, comment puis-je vérifier que l'identifiant de session qui m'a été envoyé par le client a bien été généré par moi ? Si nous ne vérifions pas, nous ne savons pas s'il s'agit d'utilisateurs connectés légitimes, et ceux qui ont de mauvaises intentions peuvent forger des identifiants de session et faire ce qu'ils veulent.
Eh bien, d'ailleurs, le point clé, c'est la vérification !
Par exemple, Little F s'est connecté au système et je lui envoie un jeton contenant l'identifiant d'utilisateur de Little F. La prochaine fois que Little F me demandera à nouveau l'accès via HTTP, ce jeton pourra être apporté. via l’en-tête Http.
Mais il n'y a pas de différence essentielle entre cela et l'identifiant de session. N'importe qui peut le falsifier, je dois donc penser à un moyen d'empêcher les autres de le falsifier.
Ensuite, je fais une signature sur les données. Par exemple, j'utilise l'algorithme HMAC-SHA256, j'ajoute une clé que moi seul connais, je fais une signature sur les données, et j'utilise cette signature et les données comme jeton. . Puisque les autres ne connaissent pas la clé, le jeton ne peut pas être falsifié.
Recommandations associées : "Tutoriel vidéo Python"
Je ne sauvegarderai pas ce jeton, quand le petit F m'enverra ce jeton Quand je viens, j'utilise le même algorithme HMAC-SHA256 et la même clé pour calculer à nouveau la signature sur les données, et je la compare avec la signature du jeton. Si elles sont identiques, je sais que Xiao F s'est connecté. et puis-je obtenir directement l'identifiant d'utilisateur du petit F. Si ce n'est pas le même, la partie données doit avoir été falsifiée, je dirai à l'expéditeur : Désolé, il n'y a pas d'authentification.
Les données du Token sont enregistrées en texte clair (même si j'utiliserai Base64 pour l'encodage, mais ce n'est pas un cryptage), elles peuvent toujours être vues par d'autres, donc Je ne peux pas y enregistrer d'informations sensibles telles que des mots de passe.
Bien sûr, si le jeton d'une personne est volé par d'autres, je ne peux rien faire. Je penserai également que le voleur est un utilisateur légitime. C'est en fait la même chose que l'identifiant de session d'une personne volé par d'autres.
De cette façon, je ne sauvegarde pas l'identifiant de session. Je génère simplement le token puis je vérifie le token, j'utilise le temps de calcul de mon CPU pour obtenir mon espace de stockage de session !
Le fardeau de l'identification de session a été allégé. On peut dire que je n'ai plus rien à craindre. Mon cluster de machines peut désormais facilement s'étendre horizontalement à mesure que le nombre de visites d'utilisateurs augmente, je peux simplement ajouter des machines directement. . Ce sentiment d’apatride est tellement bon !
Cookie
Le cookie est une chose très spécifique. Il fait référence à un type de données qui peuvent être stockées de manière permanente dans le navigateur. par la fonction de stockage du navigateur.
Le cookie est généré par le serveur et envoyé au navigateur. Le navigateur enregistre le cookie sous forme kv dans un fichier texte dans un certain répertoire. Le cookie sera envoyé au serveur la prochaine fois que le même site Web sera consulté. demandé. Étant donné que les cookies sont stockés sur le client, le navigateur a ajouté certaines restrictions pour garantir que les cookies ne seront pas utilisés de manière malveillante et n'occuperont pas trop d'espace disque. Le nombre de cookies pour chaque domaine est donc limité.
Séance
session signifie littéralement séance. C'est similaire à lorsque vous parlez à quelqu'un. Comment savez-vous que la personne à qui vous parlez est Zhang San et non Li Si ? L'autre partie doit avoir certaines caractéristiques (telles que l'apparence) qui indiquent qu'il est Zhang San.
La session est similaire. Le serveur doit savoir qui s'envoie actuellement la demande. Afin de faire cette distinction, le serveur attribuera un « identifiant d'identité » différent à chaque client. Puis à chaque fois que le client enverra une requête au serveur, il apportera cet « identifiant d'identité », et le serveur saura que la requête est en cours. vient de Qui. Quant à la manière dont le client enregistre cette « identité », il existe de nombreuses manières pour les clients navigateurs, tout le monde utilise des cookies par défaut.
Le serveur utilise la session pour enregistrer temporairement les informations de l'utilisateur sur le serveur. La session sera détruite une fois que l'utilisateur quittera le site Web. Cette méthode de stockage des informations utilisateur est plus sécurisée que les cookies, mais la session présente un défaut : si la charge du serveur Web est équilibrée, la session sera perdue lors de la prochaine demande d'opération envoyée à un autre serveur.
Jeton
L'authentification basée sur les jetons est visible partout dans le domaine Web. Dans la plupart des sociétés Internet utilisant l'API Web, les jetons constituent le meilleur moyen de gérer l'authentification de plusieurs utilisateurs.
Les fonctionnalités suivantes vous permettront d'utiliser l'authentification basée sur des jetons dans votre programme :
(1) Sans état et évolutif
(2) Prise en charge des appareils mobiles
(3) Appels inter-programmes
(4) Sécurité
Ces grands qui utilisent l'authentification basée sur les jetons, la plupart des API et des applications Web que vous avez vues utilisent toutes des jetons. Par exemple, Facebook, Twitter, Google+, GitHub, etc.
L'origine du Token
Avant de présenter les principes et les avantages de l'authentification basée sur le Token, autant jeter un œil à la façon dont l'authentification précédente était effectuée.
Vérification basée sur le serveur
Nous savons tous que le protocole HTTP est apatride et que le programme doit vérifier chaque demande pour identifier l'identité du client.
Avant cela, le programme identifiait la demande grâce aux informations de connexion stockées sur le serveur. Cette méthode est généralement réalisée en stockant Session.
Avec l'essor du Web, des applications et des terminaux mobiles, cette méthode de vérification a progressivement révélé des problèmes. Surtout quand il s'agit d'évolutivité.
Quelques problèmes exposés en fonction de la méthode d'authentification du serveur
(1) Session : chaque fois qu'un utilisateur authentifié lance une demande, le serveur doit créer un enregistrement à stocker information. Lorsque de plus en plus d’utilisateurs envoient des requêtes, la surcharge de mémoire continuera d’augmenter.
(2) Évolutivité : l'utilisation de Session pour stocker les informations de connexion dans la mémoire du serveur pose des problèmes d'évolutivité.
(3) CORS (Cross-Origin Resource Sharing) : lorsque nous devons utiliser des données sur plusieurs appareils mobiles, le partage de ressources entre domaines peut être un casse-tête. Lorsque vous utilisez Ajax pour explorer des ressources d'un autre domaine, les requêtes peuvent être interdites.
(4) CSRF (Cross-site request forgery) : Lorsque les utilisateurs visitent les sites Web des banques, ils sont vulnérables aux attaques de falsification de demandes intersites et peuvent être exploités pour accéder à d'autres sites Web.
Parmi ces problèmes, l’évolutivité est le plus important. Nous devons donc trouver une méthode plus efficace.
Principe d'authentification par jeton
L'authentification par jeton est sans état et nous ne stockons pas les informations utilisateur sur le serveur ou la session.
Ce concept résout de nombreux problèmes lors du stockage des informations côté serveur :
NoSession signifie que votre programme peut ajouter ou supprimer des machines selon les besoins sans se soucier de savoir si l'utilisateur est connecté.
Le processus d'authentification basée sur un jeton est le suivant :
(1) L'utilisateur envoie une demande via son nom d'utilisateur et son mot de passe.
(2) Vérification du programme.
(3) Le programme renvoie un jeton signé au client.
(4) Le client stocke le jeton et l'utilise pour chaque requête.
(5) Le serveur vérifie le jeton et renvoie les données.
Chaque demande nécessite un jeton. Le jeton doit être envoyé dans l'en-tête HTTP pour garantir que les requêtes HTTP sont sans état. Nous définissons également la propriété du serveur Access-Control-Allow-Origin:* pour permettre au serveur d'accepter les demandes de tous les domaines.
Il est à noter que lorsque l'en-tête ACAO est marqué (désignant) *, les certificats tels que l'authentification HTTP, le certificat SSL client et les cookies ne doivent pas être inclus.
Idées de mise en œuvre :
(1) Vérification de la connexion de l'utilisateur Après une vérification réussie, le jeton est renvoyé au client.
(2) Le client enregistre les données sur le client après les avoir reçues.
(3) Le client transporte le Token vers le serveur à chaque fois qu'il accède à l'API.
(4) Le côté serveur utilise la vérification du filtre. Si la vérification réussit, les données de la demande seront renvoyées, si la vérification échoue, un code d'erreur sera renvoyé. Après avoir authentifié les informations dans le programme et obtenu le jeton, nous pouvons faire beaucoup de choses avec ce jeton. Nous pouvons même créer un jeton basé sur une autorisation et le transmettre à des applications tierces, qui peuvent obtenir nos données (uniquement avec le jeton spécifique que nous autorisons).
Avantages des jetons
Apatride et évolutif
Jetons stockés sur le client Il est apatride et peut être étendu. Sur la base de cette apatride et de l'absence de stockage des informations de session, l'équilibreur de charge peut transférer les informations utilisateur d'un service vers d'autres serveurs.
Si nous enregistrons les informations de l'utilisateur authentifié dans Session, chaque requête nécessite que l'utilisateur envoie des informations d'authentification au serveur authentifié (appelé affinité de session). Lorsque le nombre d’utilisateurs est important, cela peut entraîner une certaine congestion.
Mais ne vous précipitez pas. Après avoir utilisé des jetons, ces problèmes sont facilement résolus, car les jetons eux-mêmes contiennent les informations de vérification de l'utilisateur.
Sécurité
L'envoi d'un token au lieu d'un cookie dans la requête peut empêcher le CSRF (contrefaçon de requête intersite). Même si un cookie est utilisé pour stocker des jetons sur le client, le cookie n'est qu'un mécanisme de stockage et n'est pas utilisé pour l'authentification. Ne pas stocker d'informations dans Session nous permet d'opérer moins de sessions.
Le jeton est limité dans le temps et les utilisateurs doivent revérifier après un certain temps. Nous n'avons pas nécessairement besoin d'attendre que le token expire automatiquement. Le token a une opération de retrait, un token spécifique ou un groupe de tokens avec la même authentification peut être invalidé.
Extensibilité
Les jetons permettent la création de programmes qui partagent des autorisations avec d'autres programmes. Par exemple, vous pouvez connecter un compte social aléatoire à votre propre compte (Fackbook ou Twitter). Lors de la connexion à Twitter via le service (nous tamponnerons ce processus), nous pouvons attacher ces tampons au flux de données Twitter (nous autorisons Buffer à publier sur notre flux Twitter).
Lorsque vous utilisez des jetons, vous pouvez fournir des autorisations facultatives à des applications tierces. Lorsque les utilisateurs souhaitent qu'une autre application accède à leurs données, nous pouvons dériver des jetons d'autorisation spéciaux en créant notre propre API.
Cross-domaine multiplateforme
Parlons à l'avance de CORS (partage de ressources inter-domaines) Lors de l'expansion d'applications et de services, vous devez intervenir dans divers domaines. Divers appareils et applications.
Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.
Tant que l'utilisateur dispose d'un jeton vérifié, les données et les ressources peuvent être demandées sur n'importe quel domaine.
Access-Control-Allow-Origin: *
Lors de la création d'un jeton basé sur des normes, vous pouvez définir certaines options. Nous le décrirons plus en détail dans les articles suivants, mais l'utilisation standard sera reflétée dans les jetons Web JSON.
Les derniers programmes et documentations sont fournis pour les jetons Web JSON. Il prend en charge de nombreuses langues. Cela signifie que vous pourrez réellement changer de mécanisme d’authentification à l’avenir.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!