1
votes

L'état de l'application n'est pas mis à jour dans un onglet de navigateur distinct

Dans mon application Angular, j'ai implémenté la confirmation par e-mail, donc lorsqu'un nouveau compte utilisateur est créé, un e-mail de confirmation sera envoyé à l'adresse e-mail enregistrée.

L'utilisateur peut se connecter sans confirmation , mais ils ont accès à des fonctionnalités limitées de l'application jusqu'à ce qu'ils visitent le lien dans l'e-mail de confirmation (le lien de confirmation ouvre l'application dans un onglet séparé).

La partie pertinente de mon AuthService ressemble à ceci:

private readonly KEY_AUTH = '_auth';

private currentAuthSubject = new BehaviorSubject<Auth>(
  JSON.parse(localStorage.getItem(this.KEY_AUTH)));

// My Components subscribe to this Observable to get notified on Auth changes
public currentAuth = this.currentAuthSubject.asObservable();

// This function is used to set the authentication object on login
// (or delete it on logout by calling setAuth(null))
setAuth(auth: Auth) {
  if (auth) {
    localStorage.setItem(this.KEY_AUTH, JSON.stringify(auth));
  } else { localStorage.removeItem(this.KEY_AUTH); }
  this.currentAuthSubject.next(auth);
}

// This function is called when the user is already logged in and being confirmed
// (by clicking the confirmation link)
setAuthConfirmed() {
  const auth = this.currentAuthSubject.value;
  if (auth) {
    auth.confirmed = true;
    localStorage.setItem(this.KEY_AUTH, JSON.stringify(auth));
    this.currentAuthSubject.next(auth);
  }
}

La confirmation fonctionne très bien, mais j'ai le cas problématique suivant:

  1. Dans l'onglet A , l'utilisateur non confirmé est connecté à l'application (fonctionnalités limitées).
  2. Dans l'onglet B , ils ouvrent leur e-mail et cliquent sur le lien de confirmation.
  3. L'application s'ouvre dans l'onglet C , la confirmation se produit et l'utilisateur dispose de toutes les fonctionnalités.

Et voici le problème:

  1. Dans l'onglet A , l'utilisateur dispose toujours des fonctionnalités limitées, même lorsqu'il navigue entre des composants abonnés à currentAuth .

    Dans cet onglet, le champ confirmé de l'objet Auth est toujours false .

    Ce problème ne peut être résolu qu'en actualisant la page.

Existe-t-il un moyen de mettre à jour l'état d'authentification dans l'onglet A sans avoir à actualiser manuellement toute la page?

J'apprécierais vraiment tout conseil.


2 commentaires

faites une requête http au serveur pour vérifier si l'e-mail est confirmé ou non toutes les 2 secondes par exemple, ou vous pouvez utiliser le websocket pour que le serveur puisse informer le navigateur de la confirmation et il sera mis à jour


Peut-être avec window.addEventListener ('storage', function (e) {... Your code there ..}); ?


5 Réponses :


-1
votes

envoyez une requête http au serveur pour vérifier si l'e-mail est confirmé ou non toutes les 2 secondes, par exemple en créant un nouveau service de repos sur votre serveur pour la vérification de confirmation d'e-mail, ou vous pouvez utiliser le websocket afin que le serveur puisse notifier le navigateur à propos de la confirmation et il sera mis à jour


0 commentaires

0
votes

Vous pouvez vous abonner aux modifications de localStorage:

window.addEventListener('storage', function(event){
    if (event.storageArea === localStorage) {
        // It's local storage
    }
}, false);

Une autre idée que vous pourriez faire est de faire un intervalle qui vérifie s'il a changé sur localStorage, si oui, vous émettez la nouvelle valeur. p>


2 commentaires

J'éviterais cela car c'est très éprouvant pour le dom. En fonction de votre application, cela peut convenir. Mais les meilleures pratiques dictent d'éviter les écouteurs d'événements lorsque cela est possible. Angular est asynchrone et réduit ainsi largement le besoin d'utiliser des écouteurs d'événements. Je comprends qu'ils sont parfois nécessaires, mais une simple autorisation de connexion devrait éviter les frais généraux liés à l'écoute des événements. De plus, il n'est pas bon pour la communauté de voter contre la réponse de tout le monde qui ne répond pas parfaitement à la question. Ce sont pour la plupart des réponses valides, mais toutes ont été rejetées. Les votes négatifs nuisent à notre réputation et nous essayons simplement de vous aider.


@kenef Pour mémoire, je n'ai contre personne, quelqu'un d'autre l'a fait.



-1
votes

Vous pouvez essayer de créer un intercepteur qui vérifierait le currentAuth à chaque demande et le mettrait à jour lorsque cela est possible et nécessaire.

Donc, dans l'onglet A , il sera mis à jour avec la première demande après la mise à jour dans l'onglet C


0 commentaires

-1
votes

Vous pouvez utiliser localstorage pour définir une sorte d'indicateur si l'utilisateur est authentifié ou non. Abonnez-vous à la Question à Stackoverflow pour la modification de l'événement localstorage .

Il y a aussi un bon article à ce sujet sur le partage de sessions entre les onglets Lien


0 commentaires

-1
votes

Pourquoi n'utilisez-vous pas ngOnInit () et ngAfterViewInit () pour gérer vos tâches pour l'onglet C?

Appelez setAuthConfirmed () dans ngOnInit (s'exécute dès que la requête est reçue mais avant le rendu de la vue) et vérifiez l'authentification des utilisateurs dans ngAfterViewInit (). Lorsque j'implémente ce que vous essayez de faire, j'utilise une classe d'utilisateurs globale qui a une portée à l'échelle de l'application. Je peux donc contrôler les affichages et les autorisations des utilisateurs connectés et non connectés avec une propriété booléenne. J'ai défini les valeurs de la classe d'utilisateurs globale dans le composant de connexion. Ensuite, chaque composant auquel on accède par la suite vérifie les propriétés de la classe d'utilisateurs pour décider comment traiter avec l'utilisateur.

Les hooks de cycle de vie vous permettront probablement d'obtenir ce que vous recherchez: https://angular.io/guide/lifecycle-hooks


0 commentaires