SPA les meilleures pratiques pour l'authentification et la gestion de session
Lors de la construction de SPA de style applications à l'aide de cadres comme Angular, Ember, de Réagir, etc. ce que les gens croient être un certain nombre de meilleures pratiques pour l'authentification et la gestion de session? Je peux penser à un couple de façons de considérer l'approche du problème.
-
Traiter de la même manière que l'authentification avec une application web en supposant que l'API et l'INTERFACE utilisateur ont la même origine domaine.
Cela nécessiterait probablement avoir un cookie de session, côté serveur de stockage de session et de la session de l'API de point de terminaison que le web authentifiés de l'INTERFACE utilisateur peut frapper pour obtenir de l'utilisateur actuel de l'information à l'aide avec la personnalisation ou peut-être même de la détermination des rôles et des capacités sur le côté client. Le serveur serait toujours d'appliquer les règles de protection de l'accès aux données de cours, l'INTERFACE serait tout simplement utiliser ces informations pour personnaliser l'expérience.
-
Traiter comme n'importe quel client tiers à l'aide d'une API publique et authentifiez-vous avec une sorte de système de jetons similaires à OAuth. Ce jeton mécanisme utilisé par l'INTERFACE utilisateur du client de s'authentifier à chaque requête faite au serveur de l'API.
Je ne suis pas vraiment beaucoup d'un expert ici, mais #1 semble être tout à fait suffisant pour la grande majorité des cas, mais j'aimerais vraiment entendre un peu plus expérimentés opinions.
- Je perfer de cette façon, stackoverflow.com/a/19820685/454252
Vous devez vous connecter pour publier un commentaire.
Cette question a été abordée, sous une forme légèrement différente, à la longueur, ici:
Réparateur D'Authentification
Mais cette adresse à partir du serveur. Regardons du côté client. Avant de faire cela, cependant, il y a un prélude important:
Javascript Crypto est Désespérée
Matasano de l'article sur ce qui est connu, mais les leçons qui y sont contenues sont assez importants:
http://www.matasano.com/articles/javascript-cryptography/
Pour résumer:
<script>
function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
Et pour ajouter un corollaire de mon propre:
Ce qui rend beaucoup de RESTful schémas d'authentification impossible ou stupide si vous avez l'intention d'utiliser un client JavaScript. Voyons!
HTTP Basic Auth
D'abord et avant tout, HTTP Basic Auth. Le plus simple des régimes: il suffit de passer un nom et un mot de passe à chaque requête.
Cela, bien sûr, nécessite absolument SSL, parce que vous êtes de passage en Base64 (réversible) codée nom et le mot de passe à chaque requête. Personne à l'écoute sur la ligne pourrait extraire nom d'utilisateur et le mot de passe de façon triviale. La plupart des "Basic Auth est d'insécurité" des arguments viennent d'un lieu de "Basic Auth sur HTTP" qui est une très mauvaise idée.
Le navigateur fournit au four-en HTTP Basic Auth soutien, mais qu'il est laid comme le péché, et vous ne devriez pas l'utiliser pour votre application. L'alternative, cependant, est de ranger les nom d'utilisateur et le mot de passe en JavaScript.
C'est la plus Reposante de la solution. Le serveur ne nécessite aucune connaissance de l'état que ce soit, et authentifie chaque individu interaction avec l'utilisateur. Un peu de REPOS amateurs (surtout strawmen) insistent pour que le maintien de toute sorte d'état est une hérésie et de l'écume à la bouche, si vous pensez à une autre méthode d'authentification. Il y a des avantages théoriques de cette sorte de respect des standards - il pris en charge par Apache hors de la boîte, vous pouvez stocker vos objets, comme des fichiers dans des dossiers protégés par .htaccess si votre cœur désirée!
La problème? Vous êtes de la mise en cache côté client, un nom d'utilisateur et mot de passe. Cela donne evil.ru une meilleure fissure à elle - même la plus simple des vulnérabilités XSS pourrait donner lieu à une transmission de son nom d'utilisateur et mot de passe pour un mal de serveur. Vous pourriez essayer d'atténuer ce risque par le malaxage et le salage le mot de passe, mais n'oubliez pas: JavaScript Crypto est Désespérée. Vous pourrait atténuer ce risque en laissant le Navigateur de Base de l'Auth soutien, mais.. laid comme le péché, comme mentionné précédemment.
HTTP Digest Auth
Est l'authentification Digest possible avec jQuery?
Plus "secure" auth, c'est une demande/réponse de hachage défi. Sauf JavaScript Crypto est Désespérée, de sorte qu'il ne fonctionne que sur SSL et vous avez encore de mettre en cache le nom d'utilisateur et mot de passe sur le côté client, le rendant plus compliqué que HTTP Basic Auth mais pas plus sécurisé.
Requête d'Authentification avec Signature Supplémentaire de Paramètres.
Un autre plus "sécurisé" auth, où vous chiffrer vos paramètres avec le nonce et les données de temps (pour protéger contre les récidivistes et les attaques temporelles) et envoyer le. L'un des meilleurs exemples est le OAuth 1.0, qui est, autant que je sache, une jolie stonking façon de mettre en œuvre l'authentification sur un serveur RESTE.
http://tools.ietf.org/html/rfc5849
Oh, mais il n'y a pas d'authentification OAuth 1.0 clients pour JavaScript. Pourquoi?
JavaScript Crypto est Désespérée, rappelez-vous. JavaScript ne peut pas participer à OAuth 1.0 sans SSL, et vous avez encore pour stocker le nom d'utilisateur du client et mot de passe local - ce qui la met dans la même catégorie que les Digérer Auth - c'est plus compliqué que HTTP Basic Auth mais c'est pas plus sécurisé.
Jeton
L'utilisateur envoie un nom d'utilisateur et le mot de passe, et reçoit en échange d'un jeton peut être utilisé pour les demandes d'authentification.
C'est un peu plus sécurisé que HTTP Basic Auth, parce que dès que le nom d'utilisateur/mot de passe de transaction est terminée, vous pouvez effacer les données sensibles. Il est également moins Reposante, comme des jetons de constituer un "état" et de faire de la mise en œuvre de serveur plus compliqué.
SSL Encore
Le hic, cependant, est que vous devez toujours vous envoyer initiale de nom d'utilisateur et le mot de passe pour obtenir un jeton. L'information sensible encore à toucher votre compromisable JavaScript.
Pour protéger vos informations d'identification utilisateur, vous devez tenir les attaquants de votre JavaScript, et vous avez encore besoin d'envoyer un nom d'utilisateur et mot de passe sur le fil. SSL Requis.
Jeton D'Expiration
Il est courant d'appliquer jeton politiques comme "hey, quand ce jeton a été autour trop long, il faut jeter et de faire de l'utilisateur de s'authentifier à nouveau." ou "je suis assez sûr que l'adresse IP uniquement autorisé à utiliser ce jeton est
XXX.XXX.XXX.XXX
". Nombre de ces politiques sont très bonnes idées.Firesheeping
Cependant, l'utilisation d'un jeton Sans SSL est toujours vulnérable à une attaque appelée "sidejacking': http://codebutler.github.io/firesheep/
L'attaquant n'obtenez pas vos informations d'identification utilisateur, mais ils peuvent encore faire semblant d'être votre utilisateur, qui peut être assez mauvais.
tl;dr: Envoi non chiffrés jetons sur le fil signifie que les attaquants peuvent facilement nab ces jetons et faire semblant d'être votre utilisateur. FireSheep est un programme qui fait cela très facile.
Une Autre Zone De Sécurité
La plus grande de l'application que vous utilisez, plus il est difficile de garantir qu'ils ne seront pas en mesure d'injecter un peu de code qui change la façon dont vous traitez des données sensibles. Vous ne faites confiance à votre CA? Vos annonceurs? Votre propre code de base?
Commun pour les détails de carte de crédit, et moins pour le nom d'utilisateur et mot de passe - certains maîtres d'œuvre conserver des données sensibles entrée " sur une page séparée du reste de leur application, une page qui peut être étroitement contrôlé et verrouillé vers le bas autant que possible, de préférence une personne qui est difficile de phish utilisateurs avec.
Cookie (signifie simplement Jeton)
Il est possible (et fréquent) pour mettre le jeton d'authentification dans un cookie. Cela ne veut pas modifier les propriétés de auth avec le jeton, c'est plus pratique. Tous ces arguments s'appliquent toujours.
Session (toujours moyen de Jeton)
Session Auth est juste des jetons d'authentification, mais avec quelques différences qui le font ressembler à un peu autre chose:
À côté de cela, cependant, il n'est pas différent de Jeton d'Authentification, vraiment.
Ce erre encore plus loin d'une bonne mise en œuvre - de l'état des objets que vous allez plus loin et plus loin sur le chemin de la plaine ol' RPC sur une dynamique de serveur.
OAuth 2.0
OAuth 2.0 regarde le problème de "Comment fonctionne le Logiciel, Un donner Logiciel B l'accès à l'Utilisateur X données sans Logiciel B ayant accès à l'Utilisateur X les informations de connexion."
La mise en œuvre est très bien juste un moyen standard pour un utilisateur pour obtenir un jeton, puis pour un service tiers pour aller "oui, oui, c'utilisateur et ce jeton match, et vous pouvez obtenir certains de leurs données à partir de maintenant."
Fondamentalement, cependant, le protocole OAuth 2.0 est juste un jeton de protocole. Il présente les mêmes propriétés que les autres jeton protocoles - vous encore besoin de SSL pour protéger ces jetons - il change juste de la façon dont ces jetons sont générés.
Il existe deux façons d'OAuth 2.0 peut vous aider à:
Mais quand il descend à lui, vous êtes juste... à l'aide de jetons.
Revenir à votre question
Alors, la question que vous posez est "dois-je conserver mon jeton dans un cookie et de mon environnement automatique de la session de gestion de prendre soin des détails, ou dois-je conserver mon jeton en Javascript et de traiter les détails à moi-même?"
Et la réponse est: faire ce qui vous rend heureux.
Le truc automatique de gestion de session, cependant, est qu'il y a beaucoup de magie qui se passe derrière les coulisses pour vous. Souvent, il est plus agréable d'être dans le contrôle de ces informations.
J'ai 21 si le protocole SSL est oui
L'autre réponse est: Utiliser le protocole https pour tout ou brigands vont voler de vos utilisateurs, mots de passe et des jetons.
It's also less RESTful, as tokens constitute "state and make the server implementation more complicated."
(1) RESTE exige le serveur d'être apatride. Un jeton stockés côté client ne représente pas l'état de façon significative pour le serveur. (2) un peu plus compliqué de code côté serveur n'a rien à voir avec de la Détente.lol_nope_send_it_to_me_instead
J'ai adoré cette fonction du nom 😀This wanders even further from a RESTful implementation - with state objects you're going further and further down the path of plain ol' RPC on a stateful server.
- c'est une pente glissante argument et est assez absurde.It's also less RESTful, as tokens constitute "state" and make the server implementation more complicated.
En fait, l'un des principaux objectifs de JWT est qu'il est apatride. Si vous voulez faire valoir de la Détente, nous devrions peut-être l'adresse de HATEOAS (ou lackthereof dans de nombreux "RESTful" Api)?Vous pouvez augmenter la sécurité dans les processus d'authentification en utilisant JWT (JSON Web Jetons) et SSL/HTTPS.
Le Basic Auth /ID de Session peuvent être volés par:
En utilisant JWT vous chiffrez l'authentification de l'utilisateur, les détails et les stocker dans le client, et de l'envoyer avec chaque requête à l'API, où le serveur/API valide le jeton.
Il ne peut pas être déchiffré/lecture sans la clé privée (dont le serveur/API magasins secrètement)Lire la mise à jour.La nouvelle (plus sécurisé), le flux serait:
De connexion
Chaque requête à l'API
Mis à jour 30.07.15:
JWT de charge/réclamations peut être lu sans la clé privée (secrète) et il n'est pas sûr de le stocker dans localStorage. Je suis désolé à propos de ces fausses déclarations. Cependant, ils semblent être de travailler sur un JWE standard (JSON Web de Cryptage).
Je l'ai fait en stockant des réclamations (userID, exp) dans un JWT, signé avec une clé privée (secrète) de l'API/backend connait et il stocké comme un HttpOnly cookie sur le client. De cette façon, il ne peut pas être lu par XSS et ne peut pas être manipulé, sinon le JWT d'échec de la vérification de la signature. Aussi à l'aide d'un sécurisé HttpOnly cookie, vous êtes en s'assurant que le cookie est envoyé uniquement via des requêtes HTTP qui n'est pas accessible pour le script) et seulement envoyés via une connexion sécurisée (HTTPS).
Mis à jour 17.07.16:
JWTs sont par nature des apatrides. Cela signifie qu'elles invalident/expire eux-mêmes. En ajoutant l'id de session dans le jeton de sinistres, vous êtes en le rendant dynamique, parce que sa validité n'est pas maintenant, ne dépendent que de vérification de signature et la date d'expiration, cela dépend aussi de l'état de session sur le serveur. Cependant, l'avantage est que vous pouvez invalider les jetons/séances facilement, que vous ne pouvais pas avant avec apatrides JWTs.
Je pencherais pour la seconde, le système de jetons.
Saviez-vous à propos de braise-auth ou braise-simple-auth? Ils utilisent tous les deux le jeton système basé sur, comme de la braise-simple-auth états:
Ils ont la gestion de session, et sont faciles à brancher sur les projets existants aussi.
Il y a aussi une Braise App Kit exemple la version de braise-simple-auth: Exemple de travail de braise-app-kit à l'aide de braise-simple-auth pour l'authentification OAuth2.