Meilleures pratiques du SPA pour l’authentification et la gestion des sessions

Lorsque vous créez des applications de style SPA en utilisant des frameworks tels que Angular, Ember, React, etc., que pensent les utilisateurs des meilleures pratiques d’authentification et de gestion des sessions? Je peux penser à quelques manières d’envisager le problème.

  1. Ne le traitez pas différemment de l’authentification avec une application Web ordinaire en supposant que l’API et l’interface utilisateur ont le même domaine d’origine.

    Cela impliquerait probablement d’avoir un cookie de session, un stockage de session côté serveur et probablement un sharepoint terminaison d’API de session que l’interface Web authentifiée peut atteindre pour obtenir les informations utilisateur actuelles pour aider à la personnalisation ou même déterminer les rôles / capacités côté client. Le serveur continuerait d’appliquer des règles protégeant l’access aux données bien sûr, l’interface utilisateur utiliserait simplement ces informations pour personnaliser l’expérience.

  2. Traitez-le comme n’importe quel client tiers utilisant une API publique et authentifiez-vous avec une sorte de système de jeton similaire à OAuth. Ce mécanisme de jeton serait utilisé par l’interface utilisateur du client pour authentifier chaque requête adressée à l’API du serveur.

Je ne suis pas vraiment un expert ici, mais le n ° 1 semble tout à fait suffisant pour la grande majorité des cas, mais j’aimerais beaucoup entendre des opinions plus expérimentées.

    Vous pouvez augmenter la sécurité dans le processus d’authentification en utilisant JWT (jetons Web JSON) et SSL / HTTPS.

    L’ID d’authentification / session de base peut être volé via:

    • Attaque MITM (Man-In-The-Middle) – sans SSL / HTTPS
    • Un intrus ayant access à l’ordinateur d’un utilisateur
    • XSS

    En utilisant JWT, vous cryptez les détails d’authentification de l’utilisateur et les stockez dans le client, et les envoyez avec chaque demande à l’API, où le serveur / API valide le jeton. Il ne peut pas être déchiffré / lu sans la clé privée (que le serveur / l’API stocke secrètement) Lire la mise à jour .

    Le nouveau stream (plus sécurisé) serait:

    S’identifier

    • L’utilisateur se connecte et envoie des identifiants de connexion à l’API (via SSL / HTTPS)
    • L’API reçoit les informations d’identification de connexion
    • Si valide:
      • Enregistrer une nouvelle session dans la firebase database Lire la mise à jour
      • Crypter l’ID utilisateur, l’ID de session, l’adresse IP, l’horodatage, etc. dans un JWT avec une clé privée.
    • L’API renvoie le jeton JWT au client (via SSL / HTTPS)
    • Le client reçoit le jeton JWT et le stocke dans localStorage / cookie

    Chaque demande à l’API

    • L’utilisateur envoie une requête HTTP à l’API (via SSL / HTTPS) avec le jeton JWT stocké dans l’en-tête HTTP
    • L’API lit l’en-tête HTTP et décrypte le jeton JWT avec sa clé privée
    • L’API valide le jeton JWT, fait correspondre l’adresse IP de la requête HTTP avec celle du jeton JWT et vérifie si la session a expiré
    • Si valide:
      • Renvoyer la réponse avec le contenu demandé
    • Si invalide:
      • Exception de jet (403/401)
      • Signaler l’intrusion dans le système
      • Envoyer un email d’avertissement à l’utilisateur.

    Mis à jour 30.07.15:

    La charge utile / les revendications JWT peuvent en fait être lues sans la clé privée (secrète) et il n’est pas sûr de la stocker dans localStorage. Je suis désolé pour ces fausses déclarations. Cependant, ils semblent travailler sur un standard JWE (JSON Web Encryption) .

    Je l’ai implémenté en stockant les revendications (userID, exp) dans un JWT, je l’ai signé avec une clé privée (secrète) que l’API / backend connaît uniquement et l’a stockée en tant que cookie HttpOnly sécurisé sur le client. De cette façon, il ne peut pas être lu via XSS et ne peut pas être manipulé, sinon le JWT échoue à la vérification de signature. De plus, en utilisant un cookie HttpOnly sécurisé , vous vous assurez que le cookie est envoyé uniquement via des requêtes HTTP (non accessibles au script) et uniquement envoyé via une connexion sécurisée (HTTPS).

    Mis à jour 17.07.16:

    Les JWT sont par nature apasortingdes. Cela signifie qu’ils invalident / expirent eux-mêmes. En ajoutant l’identifiant de session dans les revendications du jeton, vous le rendez dynamic, car sa validité ne dépend plus uniquement de la vérification de la signature et de la date d’expiration, elle dépend également de l’état de la session sur le serveur. Cependant, l’avantage est que vous pouvez invalider facilement les jetons / sessions, ce que vous ne pouviez pas faire auparavant avec les JWT sans état.

    J’irais pour le second, le système de jeton.

    Saviez-vous à propos de ember-auth ou de ember-simple-auth ? Ils utilisent tous les deux le système basé sur des jetons, comme le dit ember-simple-auth:

    Une bibliothèque légère et discrète pour l’implémentation de l’authentification basée sur des jetons dans les applications Ember.js. http://ember-simple-auth.simplabs.com

    Ils ont une gestion de session et sont faciles à twigr sur des projets existants.

    Il existe également une version exemple de Ember App Kit de ember-simple-auth: Exemple pratique de ember-app-kit utilisant ember-simple-auth pour l’authentification OAuth2.