Désolé, c'est peut-être une question que beaucoup d'autres ont posée, mais je suis vraiment confus parce que certaines références ont de nombreuses façons différentes.
J'utilise React SPA, Express, Express-session, Passport, JWT
donc je suis confus au sujet des cookies, de la session et du JWT/Passport.
De nombreux sites Web utilisent des cookies pour stocker des jetons de panier. Jusqu'à présent, j'ai stocké des données de panier basées sur l'ID de session sans ajouter de cookies.
Ainsi, lorsque les utilisateurs visitent mon site Web, je l'associe à leur
req.sessionID
, puis récupérez les données dans la base de données, comme les paniers d'achat et la session utilisateur.
donc ma question est de savoir si j'ai besoin de stocker des cookies? parce que je peux y accéder via req.sessionID pour obtenir les données nécessaires.
Et le second
J'ai effectué l'authentification à l'aide d'un passport-google-oauth20
. Une fois la connexion établie, les données sont enregistrées dans la session. et pour l'envoyer au client je dois l'envoyer via la requête URL ?token='sdsaxas'
.
dans ce cas, je reçois beaucoup de divergences d'opinion. quelqu'un l'a enregistré dans le stockage local et quelqu'un l'a enregistré dans des cookies en le convertissant en jeton à l'aide de JWT.
jwt.sign(
payload,
keys.jwt.secretOrPrivateKey,
{
expiresIn:keys.jwt.expiresIn // < i dont know what is this expired for cookies or localstorage ?
}, (err, token) => {
res.redirect(keys.Origin.url + "?token=" + token);
});
la conclusion est que tout est lié à la session, donc je peux tout faire avec sessionID? sans cookies ni stockage local
Seulement en récupérant une ou chaque page, actualisez et récupérez les données, puis enregistrées dans redux car j'utilise React SPA
Cette réponse est basée sur l'approche sans état et ne parle donc pas de la gestion de session traditionnelle
Vous avez posé deux questions totalement différentes:
En tant qu'utilisateur d'un site Web de commerce électronique, je m'attends à ce que tout article que j'ajoute à mon panier depuis mon appareil mobile lors de la navette vers mon lieu de travail, soit disponible dans le panier lorsque je me connecte au site Web depuis mon PC après être arrivé à la maison. Par conséquent, les données du panier doivent être enregistrées dans la base de données principale et liées à mon compte d'utilisateur.
En ce qui concerne l'authentification à l'aide de OAuth 2.0, le jeton d'accès JWT et/ou le jeton d'actualisation doivent être stockés quelque part sur le périphérique client, de sorte qu'une fois que l'utilisateur s'authentifie en fournissant des informations de connexion, il n'a pas besoin de fournir à nouveau ses informations d'identification pour naviguer sur le site Web. Dans ce contexte, le stockage local du navigateur, le stockage de session et les cookies sont tous des options valides. Cependant, notez qu'ici le cookie n'est lié à aucune session côté serveur. En d'autres termes, le cookie ne stocke aucun identifiant de session. Le cookie est simplement utilisé comme stockage pour le jeton d'accès qui est transmis au serveur à chaque demande http et le serveur valide ensuite le jeton à l'aide de la signature numérique pour s'assurer qu'il n'est pas falsifié et qu'il n'est pas expiré.
Bien que les trois options de stockage pour les jetons d'accès et/ou d'actualisation soient populaires, le cookie semble être l'option la plus sécurisée lorsqu'il est utilisé correctement.
Pour mieux comprendre cela, je vous recommande de lire this et this avec la spécification OAuth 2.0.
J'ai dit plus tôt que les cookies semblaient être les options les plus sécurisées. Je voudrais clarifier davantage le point ici.
La raison pour laquelle je pense que le navigateur localStorage
et sessionStorage
n'offre pas une sécurité suffisante pour stocker les jetons d'authentification est la suivante:
Si XSS se produit, le script malveillant peut facilement lire les jetons à partir de là et les envoyer à un serveur distant. Là-bas, le serveur distant ou l'attaquant n'aurait aucun problème à se faire passer pour l'utilisateur victime.
localStorage
et sessionStorage
ne sont pas partagés entre les sous-domaines. Donc, si nous avons deux SPA exécutés sur des sous-domaines différents, nous n'obtiendrons pas la fonctionnalité SSO car le jeton stocké par une application ne sera pas disponible pour l'autre application au sein de l'organisation. Il existe certaines solutions utilisant iframe
, mais celles-ci ressemblent plus à des solutions de contournement qu'à une bonne solution. Et lorsque l'en-tête de réponse X-Frame-Options
Est utilisé pour éviter les attaques de détournement de clics avec iframe
, toute solution avec iframe
est hors de question.
Ces risques peuvent cependant être atténués en utilisant une empreinte digitale (comme mentionné dans OWASP JWT Cheat Sheet ) qui à son tour nécessite un cookie.
L'idée de l'empreinte digitale est de générer une chaîne d'octets aléatoire cryptographiquement forte. La chaîne Base64 de la chaîne brute sera ensuite stockée dans un cookie HttpOnly
, Secure
, SameSite
avec le préfixe de nom __Secure-
. Les valeurs appropriées pour les attributs de domaine et de chemin doivent être utilisées conformément aux exigences de l'entreprise. Un hachage SHA256 de la chaîne sera également transmis dans une revendication de JWT. Ainsi, même si une attaque XSS envoie le jeton d'accès JWT à un serveur distant contrôlé par un attaquant, il ne peut pas envoyer la chaîne d'origine dans le cookie et, par conséquent, le serveur peut rejeter la demande en raison de l'absence du cookie. Le cookie étant HttpOnly
ne peut pas être lu par les scripts XSS.
Par conséquent, même lorsque nous utilisons localStorage
et sessionStorage
, nous devons utiliser un cookie pour le sécuriser. En plus de cela, nous ajoutons la restriction de sous-domaine comme mentionné ci-dessus.
Maintenant, la seule préoccupation concernant l'utilisation d'un cookie pour stocker JWT est l'attaque CSRF. Puisque nous utilisons le cookie SameSite
, CSRF est atténué car les demandes intersites (AJAX ou simplement via des hyperliens) ne sont pas possibles. Si le site est utilisé dans un ancien navigateur ou dans d'autres navigateurs moins populaires qui ne prennent pas en charge le cookie SameSite
, nous pouvons toujours atténuer CSRF en utilisant en outre un cookie CSRF avec une valeur aléatoire cryptographiquement forte telle que chaque AJAX lit la valeur du cookie et ajoute la valeur du cookie dans un en-tête HTTP personnalisé (sauf les requêtes GET et HEAD qui ne sont pas censées faire de modifications d'état). Étant donné que CSRF ne peut rien lire en raison de la même politique d'origine et qu'il est basé sur l'exploitation des méthodes HTTP dangereuses comme POST, PUT et DELETE, ce cookie CSRF atténuera le risque CSRF. Cette approche d'utilisation du cookie CSRF est utilisée par tous les frameworks SPA modernes. L'approche Angular est mentionnée ici .
De plus, comme le cookie est httpOnly
et Secured
, le script XSS ne peut pas le lire. Ainsi, XSS est également atténué.
Il peut également être utile de mentionner que XSS et l'injection de script peuvent être encore atténués en utilisant l'en-tête de réponse content-security-policy
Approprié.
HTTP est un protocole sans état. Lisez cette réponse pour plus de détails, mais cela signifie essentiellement que les serveurs HTTP, tels que votre serveur Web, ne stockent aucune information sur les clients au-delà de la durée de vie d'une demande. Il s'agit d'un problème pour les applications Web, car cela signifie que vous ne vous souvenez pas de l'utilisateur connecté.
Les cookies ont été inventés comme solution à cela. Les cookies sont des données textuelles que le client et le serveur envoient dans les deux sens sur demande tous. Ils vous permettent de maintenir efficacement les données sur l'état des applications, en faisant en sorte que le client et le serveur conviennent de ce dont ils se souviennent chaque fois qu'ils communiquent.
Cela signifie, fondamentalement, que vous ne pouvez pas avoir de session sans cookie . Il y a doit être un cookie qui stocke au moins l'ID de session, afin que vous puissiez savoir quel utilisateur est actuellement connecté à votre application en recherchant la session . C'est ce que fait express-session: la documentation pour la méthode principale session
note explicitement que l'ID de session est stocké dans un cookie.
donc ma question est de savoir si j'ai besoin de stocker des cookies? parce que je peux y accéder via req.sessionID pour obtenir les données nécessaires.
Vous n'avez pas besoin de stocker les cookies. express-session le fera pour vous. Votre application dans son ensemble le fait besoin de stocker un cookie; sans lui, vous n'auriez pas de req.sessionID
pour rechercher.