Maison >interface Web >js tutoriel >Implémentation d'authentification dans les applications angulaires

Implémentation d'authentification dans les applications angulaires

Joseph Gordon-Levitt
Joseph Gordon-Levittoriginal
2025-02-21 08:40:14309parcourir

Implementing Authentication in Angular Applications

Points clés

  • La mise en œuvre de l'authentification dans une seule application de page (SPA) implique le serveur exposant un point de terminaison d'authentification qui vérifie les informations d'identification de l'utilisateur et renvoie un jeton d'accès. Ce jeton est ensuite utilisé pour toutes les demandes d'API sécurisées faites au serveur.
  • Dans Angular, les jetons d'accès peuvent être stockés dans un service ou en valeur car ce sont des objets singleton sur le client. Cependant, pour éviter la perte de jetons lorsque l'utilisateur actualise la page, il est recommandé d'utiliser un mécanisme de persistance du navigateur (tel que SessionStorage) pour stocker le jeton.
  • Pour empêcher le vol de données potentiels, l'état de l'utilisateur doit être maintenu et vérifié du côté du serveur et du côté client. Lorsque l'utilisateur se déconnecte, l'API correspondante doit être appelée (le jeton d'accès est inclus dans l'en-tête de demande) et les données de SessionStorage doivent également être effacées.

L'authentification et l'autorisation sont une partie importante de presque toutes les applications sérieuses. Les applications à page unique (spas) ne font pas exception. L'application ne peut pas exposer toutes ses données et fonctionnalités à un utilisateur. Les utilisateurs peuvent avoir à s'authentifier pour afficher certaines parties de l'application ou effectuer certaines actions sur l'application. Afin d'identifier les utilisateurs de l'application, nous devons nous connecter.

Dans les applications traditionnelles de serveur et les applications à une seule page, l'implémentation de la gestion des utilisateurs est différente. La seule façon dont un spa interagit avec ses composants de serveur est via AJAX. Cela est vrai même pour la connexion et la déconnexion.

Le serveur chargé d'identifier les utilisateurs doit exposer le point de terminaison de l'authentification. Le SPA enverra les informations d'identification entre l'utilisateur à ce point de terminaison pour vérification. Dans un système d'authentification basé sur le jeton typique, un service peut renvoyer un jeton d'accès ou un objet contenant le nom et le rôle de l'utilisateur connecté après vérification des informations d'identification. Le client doit utiliser ce jeton d'accès dans toutes les demandes d'API sécurisées faites au serveur.

Étant donné que le jeton d'accès sera utilisé plusieurs fois, il est préférable de le stocker sur le client. Dans Angular, nous pouvons stocker des valeurs dans un service ou en valeurs car ce sont des objets singleton sur le client. Cependant, si l'utilisateur actualise la page, la valeur du service ou de la valeur sera perdue. Dans ce cas, il est préférable d'utiliser l'un des mécanismes de persistance fournis par le navigateur pour stocker le jeton;

Atteindre la connexion

Regardons maintenant un code. Supposons que nous ayons implémenté toute la logique côté serveur et que le service expose un point de terminaison de repos à / API / Connexion pour vérifier les informations d'identification de connexion et renvoyer le jeton d'accès. Écrivons un service simple qui effectue des opérations de connexion en accédant au point de terminaison de l'authentification. Nous ajouterons plus de fonctionnalités à ce service plus tard:

<code class="language-javascript">app.factory("authenticationSvc", function($http, $q, $window) {
  var userInfo;

  function login(userName, password) {
    var deferred = $q.defer();

    $http.post("/api/login", {
      userName: userName,
      password: password
    }).then(function(result) {
      userInfo = {
        accessToken: result.data.access_token,
        userName: result.data.userName
      };
      $window.sessionStorage["userInfo"] = JSON.stringify(userInfo);
      deferred.resolve(userInfo);
    }, function(error) {
      deferred.reject(error);
    });

    return deferred.promise;
  }

  return {
    login: login
  };
});</code>

Dans le code réel, vous souhaiterez peut-être refacter les instructions qui stockent les données à SessionStorage dans un service distinct, car si nous faisons cela, ce service assumera plusieurs responsabilités. Pour garder la démo simple, je le garde dans le même service. Ce service peut être utilisé par un contrôleur qui gère la fonction de connexion de l'application.

Protection de l'itinéraire

Nous pouvons avoir un ensemble de routes protégées dans notre application. Si l'utilisateur n'est pas connecté et essaie de saisir l'un de ces itinéraires, l'utilisateur doit être dirigé vers la page de connexion. Cela peut être fait en utilisant le bloc Resolve dans les options de routage. L'extrait de code suivant illustre l'implémentation:

<code class="language-javascript">$routeProvider.when("/", {
  templateUrl: "templates/home.html",
  controller: "HomeController",
  resolve: {
    auth: ["$q", "authenticationSvc", function($q, authenticationSvc) {
      var userInfo = authenticationSvc.getUserInfo();

      if (userInfo) {
        return $q.when(userInfo);
      } else {
        return $q.reject({ authenticated: false });
      }
    }]
  }
});</code>
Le bloc

Resolve peut contenir plusieurs blocs d'instructions qui doivent renvoyer un objet de promesse à la fin. Juste pour clarifier, le nom de l'authentification ci-dessus n'est pas défini par le cadre; je l'ai défini. Vous pouvez modifier le nom en n'importe quel nom en fonction du cas d'utilisation.

Il y a plusieurs raisons qui peuvent entraîner le dépassement ou rejeter le routage. Selon le scénario, vous pouvez transmettre des objets lors de l'analyse / rejet des promesses. Nous n'avons pas implémenté la méthode getLoggedInuser () dans le service. Il s'agit d'un moyen facile de retourner un objet LoggedInUser du service.

<code class="language-javascript">app.factory("authenticationSvc", function() {
  var userInfo;

  function getUserInfo() {
    return userInfo;
  }
});</code>

L'objet envoyé par promesse dans l'extrait de code ci-dessus est diffusé via $ rootscope. Si l'itinéraire a été résolu, l'événement $ RoutechangeSuccess est diffusé. Cependant, si le routage échoue, l'événement $ RouteChangeError est diffusé. Nous pouvons écouter l'événement $ RouteChangeError et rediriger l'utilisateur vers la page de connexion. Étant donné que les événements sont au niveau de Rootscope, il est préférable de fixer un gestionnaire d'événements dans le bloc de course.

<code class="language-javascript">app.run(["$rootScope", "$location", function($rootScope, $location) {
  $rootScope.$on("$routeChangeSuccess", function(userInfo) {
    console.log(userInfo);
  });

  $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {
    if (eventObj.authenticated === false) {
      $location.path("/login");
    }
  });
}]);</code>

Rafraîchissement de la page de traitement

Lorsqu'un utilisateur clique sur le bouton Actualiser la page, le service perd son statut. Nous devons obtenir les données de la SessionStorage du navigateur et les attribuer à la variable loggedInUser. Étant donné que l'usine n'est appelée qu'une seule fois, nous pouvons définir cette variable dans la fonction d'initialisation comme indiqué ci-dessous.

<code class="language-javascript">function init() {
  if ($window.sessionStorage["userInfo"]) {
    userInfo = JSON.parse($window.sessionStorage["userInfo"]);
  }
}

init();</code>

Annuler

Lorsque l'utilisateur se déconnecte de l'application, l'API correspondante doit être appelé et le jeton d'accès est inclus dans l'en-tête de demande. Une fois que l'utilisateur s'est déconnecté, nous devons également effacer les données dans SessionStorage. L'exemple suivant contient la fonction de déconnexion qui doit être ajoutée au service d'authentification.

<code class="language-javascript">function logout() {
  var deferred = $q.defer();

  $http({
    method: "POST",
    url: logoutUrl,
    headers: {
      "access_token": userInfo.accessToken
    }
  }).then(function(result) {
    $window.sessionStorage["userInfo"] = null;
    userInfo = null;
    deferred.resolve(result);
  }, function(error) {
    deferred.reject(error);
  });

  return deferred.promise;
}</code>

Conclusion

La méthode d'implémentation d'authentification dans une seule application de page est très différente de celle des applications Web traditionnelles. Étant donné que la plupart des travaux sont effectués sur le client, le statut de l'utilisateur doit également être stocké quelque part sur le client. Il est important de se rappeler que l'état doit également être maintenu et vérifié du côté du serveur, car les pirates peuvent voler des données stockées sur le système client.

Le code source de cet article peut être téléchargé sur GitHub.

FAQs sur l'implémentation de l'authentification dans les applications angulaires

Comment utiliser la propriété WithCredentials en Angular?

La propriété

WithCredentials est utilisée pour inclure des cookies d'authentification dans les demandes HTTP. Dans Angular, vous pouvez l'utiliser dans le module httpclient. Lorsque vous faites une demande, vous pouvez définir la propriété WithCredentials sur true. Voici un exemple:

this.http.get(url, { withCredentials: true }).subscribe(...);

Cela contiendra tous les cookies qui pourraient avoir été envoyés devant le serveur.

Quel est le but de Httpinterceptor dans Angular?

httpinterceptor est une fonctionnalité en angulaire qui vous permet d'intercepter et de modifier les demandes HTTP à l'échelle mondiale avant de les envoyer au serveur. Il est très utile pour diverses tâches, comme l'ajout d'un jeton d'authentification à toutes les demandes ou la gestion des erreurs globales.

Comment créer un HTTPInterceptor personnalisé pour gérer les création de création?

Pour créer un httpinterceptor personnalisé, vous devez créer un service qui implémente l'interface httpinterceptor. Voici un exemple:

<code class="language-javascript">app.factory("authenticationSvc", function($http, $q, $window) {
  var userInfo;

  function login(userName, password) {
    var deferred = $q.defer();

    $http.post("/api/login", {
      userName: userName,
      password: password
    }).then(function(result) {
      userInfo = {
        accessToken: result.data.access_token,
        userName: result.data.userName
      };
      $window.sessionStorage["userInfo"] = JSON.stringify(userInfo);
      deferred.resolve(userInfo);
    }, function(error) {
      deferred.reject(error);
    });

    return deferred.promise;
  }

  return {
    login: login
  };
});</code>

Cet intercepteur clones chaque demande et définit la propriété WithCredentials à true.

Pourquoi recevez-vous une erreur CORS lors de l'utilisation de WithCredentials?

CORS (partage de ressources à original) est une fonctionnalité de sécurité qui limite la façon dont les ressources sont partagées entre les domaines. Si vous recevez une erreur CORS, le serveur n'est pas configuré pour accepter les demandes de votre domaine. Pour résoudre ce problème, vous devez configurer le serveur pour inclure votre domaine dans l'en-tête "Access-Control-Allow-Origin" et définir "Access-Control-Allow-Credentials" sur True.

Comment utiliser la propriété XMLHTTPREQUEST WITCIELS?

La propriété XMLHTTPREQUEST WITCIELS fonctionne de manière similaire à la propriété Angular HttpClient WitalEntials. Il est utilisé pour inclure des cookies dans la demande. Voici un exemple:

<code class="language-javascript">$routeProvider.when("/", {
  templateUrl: "templates/home.html",
  controller: "HomeController",
  resolve: {
    auth: ["$q", "authenticationSvc", function($q, authenticationSvc) {
      var userInfo = authenticationSvc.getUserInfo();

      if (userInfo) {
        return $q.when(userInfo);
      } else {
        return $q.reject({ authenticated: false });
      }
    }]
  }
});</code>

Cela enverra une demande GET contenant le cookie à l'URL spécifiée.

Les FAQ restantes sont liées à l'utilisation de httpclientmodule et ont peu à voir avec le sujet de base de l'article (l'implémentation d'authentification en angulaire), ils sont donc omis ici. Ces questions peuvent être facilement trouvées via les moteurs de recherche.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn