Depuis plusieurs jours maintenant, j'ai été à la recherche pour une sécurité d'authentification et de session d'un mécanisme de gestion pour mon single page application. À en juger par les nombreux tutoriels et des articles de blog sur les SPAs et d'authentification, le stockage JWTs dans localStorage ou les témoins réguliers semble être l'approche la plus commune, mais il n'est tout simplement pas une bonne idée d'utiliser JWTs pour les sessions il n'est donc pas une option pour cette application.
Exigences
- Les connexions devraient être révoquées. Par exemple, si une activité suspecte est détectée sur le compte d'un utilisateur, il devrait être possible de révoquer l'accès de cet utilisateur immédiatement et nécessitent un nouveau journal dans. De même, des choses comme les réinitialisations de mot de passe doit annuler toutes les connexions.
- L'authentification devrait arriver au cours de l'Ajax. Pas de redirection du navigateur ("dur" redirection) devrait avoir lieu à la suite. Tous les éléments de navigation doivent se produire à l'intérieur du SPA.
- Tout devrait fonctionner inter-domaine. Le SPA sera sur www.domain1.com et le serveur sera sur www.domain2.com.
- JavaScript doit avoir aucun accès à des données sensibles envoyées par le serveur, comme des Identifiants de session. C'est pour empêcher les attaques XSS où des scripts malveillants peuvent voler les jetons ou les Id de session à partir les témoins réguliers, localStorage ou sessionStorage.
Le mécanisme idéal semble être basée sur le cookie d'authentification à l'aide d' HttpOnly
les cookies qui contiennent des Identifiants de session. Le flux serait de travailler comme ceci:
- L'utilisateur arrive sur une page de login et soumet leur nom d'utilisateur et mot de passe.
- Le serveur authentifie l'utilisateur et envoie un ID de session comme un
HttpOnly
réponse cookie. - Le SPA, puis comprend ce cookie dans la suite XHR requêtes faites au serveur. Cela semble être possible, à l'aide de l'
withCredentials
option. - Quand une demande est faite à un ordinateur d'extrémité protégé, le serveur recherche le cookie. Si elle est trouvée, il la croix-vérifie que l'ID de session à l'encontre d'une table de base de données pour s'assurer que la session est toujours valide.
- Lorsque l'utilisateur se déconnecte, la session est supprimée de la base de données. La prochaine fois que l'utilisateur arrive sur le site, le SPA devient un 401/403 réponse (depuis la session a expiré), puis prend de l'utilisateur à l'écran de connexion.
Parce que le cookie HttpOnly
drapeau, JavaScript ne serait pas en mesure de lire son contenu, de sorte qu'il serait à l'abri des attaques tant qu'il est transmis via le protocole HTTPS.
Défis
Voici la question que j'ai pu croiser. Mon serveur est configuré pour gérer les CORS des demandes. Après l'authentification de l'utilisateur, il envoie correctement le cookie dans la réponse:
HTTP/1.1 200 OK
server: Cowboy
date: Wed, 15 Mar 2017 22:35:46 GMT
content-length: 59
set-cookie: _myapp_key=SFMyNTYBbQAAABBn; path=/; HttpOnly
content-type: application/json; charset=utf-8
cache-control: max-age=0, private, must-revalidate
x-request-id: qi2q2rtt7mpi9u9c703tp7idmfg4qs6o
access-control-allow-origin: http://localhost:8080
access-control-expose-headers:
access-control-allow-credentials: true
vary: Origin
Toutefois, le navigateur n'enregistre pas le cookie (quand je vérifie Chrome local de cookies, il n'est pas là). Ainsi, lorsque le code suivant fonctionne:
context.axios.post(LOGIN_URL, creds).then(response => {
context.$router.push("/api/account")
}
Et la page de votre Compte est créé:
created() {
this.axios.get(SERVER_URL + "/api/account/", {withCredentials: true}).then(response => {
//do stuff
}
}
Cet appel n'a pas le cookie dans l'en-tête. Le serveur donc il rejette.
GET /api/account/ HTTP/1.1
Host: localhost:4000
Connection: keep-alive
Accept: application/json
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,tr;q=0.6
Ai-je besoin de faire quelque chose de spécial pour vous assurer que le navigateur enregistre le cookie après la réception de la réponse de connexion? Diverses sources que j'ai lus ont dit que les navigateurs enregistrer la réponse des témoins uniquement lorsque l'utilisateur est redirigé, mais je ne veux pas de "dur" redirige puisque c'est un SPA.
Le SPA en question est écrit en Vue.js mais je suppose que cela s'applique à tous les SPAs. Je me demande comment les gens à gérer ce scénario.
Autres trucs que j'ai lu sur ce sujet: