Authentification basée sur les jetons avec AngularJS et NodeJS

Ce que vous allez créer

L'authentification est l'une des parties les plus importantes de toute application Web. Dans ce didacticiel, nous aborderons les systèmes d’authentification par jetons et leurs différences avec les systèmes de connexion traditionnels. À la fin de ce tutoriel, vous verrez une démo entièrement fonctionnelle écrite en AngularJS et NodeJS..

Vous pouvez également trouver une large sélection de scripts et d'applications d'authentification prêts à l'emploi sur Envato Market, tels que:

  • EasyLogin Pro - Système d'adhésion utilisateur
  • Génération de clés PHP et classe d'authentification
  • Outil d'administration de rôle de membre
  • Angry Frog Script de connexion PHP
  • CakePHP Plugin d'authentification et de gestion des ACL

Ou, si vous rencontrez des problèmes avec votre code AngularJS, vous pouvez le soumettre à araneux sur Envato Studio pour le corriger..

Systèmes d'authentification traditionnels

Avant de passer à un système d’authentification par jeton, jetons un coup d’œil sur un système d’authentification traditionnel.

  1. L'utilisateur fournit un Nom d'utilisateur et mot de passe dans le formulaire de connexion et clics S'identifier.
  2. Une fois la demande effectuée, validez l'utilisateur sur le serveur en effectuant une interrogation dans la base de données. Si la demande est valide, créez une session en utilisant les informations utilisateur extraites de la base de données, puis renvoyez-les dans l'en-tête de la réponse afin de stocker l'ID de session dans le navigateur..
  3. Fournir les informations de session pour accéder aux points de terminaison restreints dans l'application.
  4. Si les informations de session sont valides, laissez l'utilisateur accéder aux points de terminaison spécifiés et répondez avec le contenu HTML affiché..

Tout va bien jusqu'à ce point. L'application Web fonctionne bien et permet d'authentifier les utilisateurs afin qu'ils puissent accéder aux points de terminaison restreints. Cependant, que se passe-t-il lorsque vous souhaitez développer un autre client, par exemple pour Android, pour votre application? Serez-vous capable d'utiliser l'application actuelle pour authentifier les clients mobiles et servir du contenu restreint? Dans l'état actuel des choses, non. Il y a deux raisons principales pour cela:

  1. Les sessions et les cookies n'ont pas de sens pour les applications mobiles. Vous ne pouvez pas partager des sessions ou des cookies créés côté serveur avec des clients mobiles.
  2. Dans l'application en cours, le code HTML rendu est renvoyé. Dans un client mobile, vous avez besoin que quelque chose comme JSON ou XML soit inclus comme réponse..

Dans ce cas, vous avez besoin d’une application indépendante du client..

Authentification basée sur les jetons

Dans l'authentification par jeton, les cookies et les sessions ne seront pas utilisés. Un jeton sera utilisé pour authentifier un utilisateur pour chaque demande adressée au serveur. Reconcevons le premier scénario avec l'authentification par jeton.

Il utilisera le flux de contrôle suivant:

  1. L'utilisateur fournit un Nom d'utilisateur et mot de passe dans le formulaire de connexion et clics S'identifier.
  2. Une fois la demande effectuée, validez l'utilisateur sur le serveur en effectuant une interrogation dans la base de données. Si la demande est valide, créez un jeton à l'aide des informations utilisateur extraites de la base de données, puis renvoyez-les dans l'en-tête de la réponse afin que nous puissions stocker le navigateur de jetons dans la mémoire de stockage locale..
  3. Fournir des informations de jeton dans chaque en-tête de demande pour accéder aux points de terminaison restreints de l'application.
  4. Si le jeton extrait des informations d'en-tête de demande est valide, laissez l'utilisateur accéder au point de terminaison spécifié et répondez avec JSON ou XML..

Dans ce cas, nous n’avons pas renvoyé de session ni de cookie, et nous n’avons renvoyé aucun contenu HTML. Cela signifie que nous pouvons utiliser cette architecture pour tout client pour une application spécifique. Vous pouvez voir le schéma d'architecture ci-dessous:

Alors, quelle est cette JWT?

JWT

JWT signifie Jeton Web JSON et est un format de jeton utilisé dans les en-têtes d'autorisation. Ce jeton vous aide à concevoir la communication entre deux systèmes de manière sécurisée. Reformulons JWT en tant que "jeton porteur" aux fins de ce didacticiel. Un jeton porteur se compose de trois parties: en-tête, charge utile et signature.

  • L'en-tête est la partie du jeton qui conserve le type de jeton et la méthode de cryptage, qui est également crypté avec base 64.
  • La charge inclut l'information. Vous pouvez mettre n'importe quel type de données telles que les informations sur l'utilisateur, les informations sur le produit, etc., qui sont toutes stockées avec le cryptage en base 64.
  • La signature consiste en une combinaison de l'en-tête, de la charge utile et de la clé secrète. La clé secrète doit être conservée en toute sécurité côté serveur..

Vous pouvez voir le schéma JWT et un exemple de jeton ci-dessous;

Il n'est pas nécessaire d'implémenter le générateur de jetons du support, car vous pouvez rechercher des versions qui existent déjà dans plusieurs langues. Vous pouvez en voir quelques-unes ci-dessous:

La langue URL de la bibliothèque
NodeJS http://github.com/auth0/node-jsonwebtoken
PHP http://github.com/firebase/php-jwt
Java http://github.com/auth0/java-jwt
Rubis http://github.com/progrium/ruby-jwt
.NET http://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet
Python http://github.com/progrium/pyjwt/

Un exemple pratique

Après avoir couvert quelques informations de base sur l’authentification par jeton, nous pouvons maintenant passer à un exemple concret. Jetez un coup d’œil au schéma suivant, après quoi nous l’analyserons plus en détail:

  1. Les demandes sont effectuées par plusieurs clients, tels qu'une application Web, un client mobile, etc., à l'API dans un but spécifique..
  2. Les demandes sont faites à un service comme https://api.yourexampleapp.com. Si de nombreuses personnes utilisent l'application, plusieurs serveurs peuvent être nécessaires pour exécuter l'opération demandée..
  3. Ici, l'équilibreur de charge est utilisé pour équilibrer les demandes afin qu'elles correspondent le mieux aux serveurs d'applications du back-end. Lorsque vous faites une demande à https://api.yourexampleapp.com, L'équilibreur de charge va d'abord gérer une requête, puis il redirige le client vers un serveur spécifique..
  4. Il existe une application et cette application est déployée sur plusieurs serveurs (serveur-1, serveur-2,…, serveur-n). Chaque fois qu'une demande est faite à https://api.yourexampleapp.com, l'application dorsale interceptera l'en-tête de demande et extraira les informations de jeton de l'en-tête d'autorisation. Une requête de base de données sera faite en utilisant ce jeton. Si ce jeton est valide et dispose de l'autorisation requise pour accéder au noeud final demandé, il continue. Si non, il retournera un code de réponse 403 (qui indique un statut interdit).

Avantages

L'authentification par jeton présente plusieurs avantages qui résolvent les problèmes graves. Certains d'entre eux sont les suivants:

  • Services indépendants du client. Dans l'authentification par jeton, un jeton est transféré via des en-têtes de demande, au lieu de conserver les informations d'authentification dans des sessions ou des cookies. Cela signifie qu'il n'y a pas d'état. Vous pouvez envoyer une requête au serveur à partir de tout type de client pouvant effectuer des requêtes HTTP..
  • CDN. Dans la plupart des applications Web actuelles, les vues sont rendues sur le back-end et le contenu HTML est renvoyé au navigateur. La logique frontale dépend du code back-end. Il n'y a pas besoin de faire une telle dépendance. Cela vient avec plusieurs problèmes. Par exemple, si vous travaillez avec une agence de conception qui implémente votre code HTML, CSS et JavaScript front-end, vous devez extraire ce code et le migrer vers votre code d’arrière-plan afin d’effectuer un rendu ou un remplissage. opérations. Après un certain temps, votre contenu HTML affiché sera très différent de ce que l'agence de code a implémenté. Dans l'authentification par jeton, vous pouvez développer un projet frontal séparément du code back-end. Votre code back-end retournera une réponse JSON au lieu d'un HTML rendu et vous pourrez insérer la version réduite, gzippée du code front-end dans le CDN. Lorsque vous accédez à votre page Web, le contenu HTML est fourni à partir du CDN et le contenu de la page est renseigné par les services API à l'aide du jeton contenu dans les en-têtes d'autorisation.
  • Pas de cookie-session (ou pas de CSRF). CSRF est un problème majeur de la sécurité Web moderne car il ne vérifie pas si une source de demande est approuvée ou non. Pour résoudre ce problème, un pool de jetons est utilisé pour envoyer ce jeton sur chaque publication de formulaire. Dans l'authentification par jeton, un jeton est utilisé dans les en-têtes d'autorisation et CSRF n'inclut pas cette information..
  • Magasin de jetons persistant. Lorsqu'une session en lecture, écriture ou suppression est effectuée dans l'application, elle crée une opération de fichier dans le système d'exploitation. temp dossier, au moins pour la première fois. Disons que vous avez plusieurs serveurs et qu'une session est créée sur le premier serveur. Lorsque vous effectuez une autre demande et que celle-ci tombe sur un autre serveur, les informations de session n'existent pas et obtiennent une réponse "non autorisée". Je sais, vous pouvez résoudre cela avec une session collante. Cependant, dans l'authentification par jeton, ce cas est résolu naturellement. Il n'y a pas de problème de session collante, car le jeton de demande est intercepté à chaque demande sur n'importe quel serveur..

Ce sont les avantages les plus courants de l'authentification et de la communication basées sur des jetons. C'est la fin du discours théorique et architectural sur l'authentification par jeton. Temps pour un exemple pratique.

Un exemple d'application

Vous verrez deux applications pour démontrer l'authentification par jeton:

  1. back-toh-auth-backend basé sur un jeton
  2. token-based-auth-frontend

Dans le projet principal, il y aura des implémentations de services et les résultats des services seront au format JSON. Il n'y a pas de vue retournée dans les services. Dans le projet frontal, il y aura un projet AngularJS pour le code HTML frontal, puis l'application frontale sera remplie par les services AngularJS pour faire des demandes aux services principaux..

back-toh-auth-backend basé sur un jeton

Dans le projet back-end, il y a trois fichiers principaux:

  • package.json est pour la gestion de la dépendance.
  • models \ User.js contient un modèle utilisateur qui sera utilisé pour effectuer des opérations de base de données sur les utilisateurs.
  • server.js est destiné au démarrage du projet et à la gestion des demandes.

C'est tout! Ce projet est très simple, vous permettant de comprendre facilement le concept principal sans faire de plongée..

"name": "angular-restful-auth", "version": "0.0.1", "dépendances": "express": "4.x", "analyseur de corps": "~ 1.0.0" , "morgan": "dernier", "mangouste": "3.8.8", "jsonwebtoken": "0.4.0", "moteurs": "noeud": "> = 0.10.0"

package.json contient des dépendances pour le projet: Express pour MVC, analyseur de corpspour simuler le traitement des demandes de post dans NodeJS, Morganpour la journalisation des demandes, mangoustepour que notre cadre ORM se connecte à MongoDB, et jsonwebtoken pour créer des jetons JWT à l’aide de notre modèle d’utilisateur. Il y a aussi un attribut appelé moteurs cela dit que ce projet est fait en utilisant NodeJS version> = 0.10.0. Ceci est utile pour les services PaaS comme Heroku. Nous allons également couvrir ce sujet dans une autre section.

var mangouste = require ('mangouste'); var Schema = mongoose.Scema; var UserSchema = new Schema (email: String, mot de passe: String, jeton: String); module.exports = mongoose.model ('User', UserSchema);

Nous avons dit que nous générerions un jeton en utilisant la charge utile du modèle utilisateur. Ce modèle nous aide à effectuer des opérations utilisateur sur MongoDB. Dans User.js, le schéma utilisateur est défini et le modèle utilisateur est créé à l'aide d'un modèle mangouste. Ce modèle est prêt pour les opérations de base de données.

Nos dépendances sont définies et notre modèle utilisateur est défini. Nous allons donc maintenant combiner tous ceux-ci pour créer un service permettant de traiter des demandes spécifiques..

// Modules requis var express = require ("express"); var morgan = require ("morgan"); var bodyParser = require ("analyseur de corps"); var jwt = require ("jsonwebtoken"); var mangouste = require ("mangouste"); var app = express ();

Dans NodeJS, vous pouvez inclure un module dans votre projet en utilisant exiger. Premièrement, nous devons importer les modules nécessaires dans le projet:

var port = process.env.PORT || 3001; var User = require ('./ models / User'); // Connexion à la base de données mongoose.connect (process.env.MONGO_URL);

Notre service desservira un port spécifique. Si une variable de port est définie dans les variables d’environnement système, vous pouvez l’utiliser ou vous avez défini le port. 3001. Après cela, le modèle utilisateur est inclus et la connexion à la base de données est établie afin d'effectuer certaines opérations utilisateur. N'oubliez pas de définir une variable d'environnement-MONGO_URL-pour l'URL de connexion à la base de données.

app.use (bodyParser.urlencoded (extended: true)); app.use (bodyParser.json ()); app.use (morgan ("dev")); app.use (function (req, res, next) res.setHeader ('Access-Control-Allow-Origin', '*'); res.setHeader ('Access-Control-Allow-Methods-Method', 'GET, POST res.setHeader ('Accès-Contrôle-Autoriser-En-têtes', 'X-Demandé avec, type de contenu, autorisation'); next (););

Dans la section ci-dessus, nous avons effectué certaines configurations pour simuler la gestion d'une requête HTTP dans NodeJS à l'aide d'Express. Nous permettons aux demandes de venir de différents domaines afin de développer un système indépendant du client. Si vous ne le permettez pas, vous allez provoquer une erreur CORS (Cross Origin Request Sharing) dans le navigateur Web..

  • Access-Control-Allow-Origin autorisé pour tous les domaines.
  • Vous pouvez envoyer POSTER et OBTENIR demandes à ce service.
  • X-Demandé Avec et type de contenu les en-têtes sont autorisés.
app.post ('/ authenticate', fonction (req, res) User.findOne (email: req.body.email, mot de passe: req.body.password, fonction (err, utilisateur) if (err)  res.json (type: false, données: "Une erreur s'est produite:" + err); else si (utilisateur) res.json (type: true, données: utilisateur, jeton: utilisateur.token);  else res.json (type: false, data: "E-mail / mot de passe incorrect");););

Nous avons importé tous les modules requis et défini notre configuration. Le moment est donc venu de définir des gestionnaires de requêtes. Dans le code ci-dessus, chaque fois que vous faites un POSTERdemande à /authentifier avec nom d'utilisateur et mot de passe, vous obtiendrez un JWT jeton. Tout d'abord, la requête dans la base de données est traitée à l'aide d'un nom d'utilisateur et d'un mot de passe. Si un utilisateur existe, les données utilisateur seront renvoyées avec son jeton. Mais que se passe-t-il si aucun utilisateur ne correspond au nom d'utilisateur et / ou au mot de passe?

app.post ('/ signin', fonction (req, res) User.findOne (email: req.body.email, mot de passe: req.body.password, ​​fonction (err, utilisateur) if (err)  res.json (type: false, données: "Une erreur s'est produite:" + err); else si (utilisateur) res.json (type: false, données: "l'utilisateur existe déjà!"); else var userModel = new User (); userModel.email = req.body.email; userModel.password = req.body.password; userModel.save (function (err, utilisateur) user.token = jwt.sign (utilisateur , process.env.JWT_SECRET); user.save (function (err, user1) res.json (type: true, données: utilisateur1, jeton: utilisateur1.token);)); );

Quand tu fais un POSTER demande à /se connecter avec nom d'utilisateur et mot de passe, un nouvel utilisateur sera créé à l'aide des informations d'utilisateur publiées. Sur le 19ème ligne, vous pouvez voir qu’un nouveau jeton JSON est généré à l’aide de la touche jsonwebtoken module, qui a été affecté à la jwt variable. La partie authentification est OK. Et si nous essayions d'accéder à un point de terminaison restreint? Comment pouvons-nous réussir à accéder à ce point final?

app.get ('/ me', EnsureAuthorized, function (req, res) User.findOne (token: req.token, function (err, utilisateur) if (err) res.json (type: false , data: "Une erreur est survenue:" + err); else res.json (type: true, data: utilisateur);););

Quand tu fais un OBTENIR demande à /moi, vous obtiendrez les informations de l'utilisateur actuel, mais pour continuer avec le point final demandé, le assurerAutorisé la fonction sera exécutée.

function assureAuthorized (req, res, next) var bearerToken; var bearerHeader = req.headers ["autorisation"]; if (typeof bearerHeader! == 'undefined') var bearer = bearerHeader.split (""); porteurToken = porteur [1]; req.token = bearerToken; suivant();  else res.send (403); 

Dans cette fonction, les en-têtes de requête sont interceptés et les autorisation l'en-tête est extrait. S'il existe un jeton porteur dans cet en-tête, ce jeton est attribué à req.token afin d'être utilisé tout au long de la demande, et la demande peut être continuée en utilisant suivant(). Si un jeton n'existe pas, vous obtiendrez une réponse 403 (interdite). Revenons au handler /moi, et utilise req.token récupérer les données utilisateur avec ce jeton. Chaque fois que vous créez un nouvel utilisateur, un jeton est généré et enregistré dans le modèle utilisateur dans la base de données. Ces jetons sont uniques.

Nous n'avons que trois gestionnaires pour ce projet simple. Après cela, vous verrez.

process.on ('uncaughtException', function (err) console.log (err););

L'application NodeJS peut se bloquer si une erreur se produit. Avec le code ci-dessus, cette panne est évitée et un journal des erreurs est imprimé dans la console. Et enfin, nous pouvons démarrer le serveur en utilisant l'extrait de code suivant. 

// Démarrer le serveur app.listen (port, fonction () console.log ("Écoute du serveur sur le port" + port););

Pour résumer:

  • Les modules sont importés.
  • Les configurations sont faites.
  • Les gestionnaires de demandes sont définis.
  • Un middleware est défini afin d'intercepter les points de terminaison restreints.
  • Le serveur est démarré.

Nous avons terminé avec le service back-end. Pour qu’elle puisse être utilisée par plusieurs clients, vous pouvez déployer cette application serveur simple sur vos serveurs, ou peut-être déployer dans Heroku. Il y a un fichier appelé Procfile dans le dossier racine du projet. Déploiement de notre service à Heroku.

Déploiement d'Heroku

Vous pouvez cloner le projet principal à partir de ce référentiel GitHub..

Je ne discuterai pas de la création d'une application dans Heroku; vous pouvez vous référer à cet article pour créer une application Heroku si vous ne l'avez pas déjà fait auparavant. Après avoir créé votre application Heroku, vous pouvez ajouter une destination à votre projet actuel à l'aide de la commande suivante:

git à distance ajouter heroku 

Vous avez maintenant cloné un projet et ajouté une destination. Après git ajouter et git commit, vous pouvez transmettre votre code à Heroku en effectuant git push maître heroku. Lorsque vous réussissez à pousser un projet, Heroku exécute le npm installer commande pour télécharger des dépendances dans le temp dossier sur Heroku. Après cela, votre application démarrera et vous pourrez accéder à votre service en utilisant le protocole HTTP..

token-based-auth-frontend

Dans le projet frontal, vous verrez un projet AngularJS. Ici, je ne mentionnerai que les sections principales du projet frontal, car AngularJS n’est pas quelque chose qui peut être traité dans un seul tutoriel..

Vous pouvez cloner le projet à partir de ce référentiel GitHub. Dans ce projet, vous verrez la structure de dossiers suivante:

ngStorage.js est une bibliothèque pour AngularJS permettant de manipuler des opérations de stockage locales. En outre, il y a une disposition principale index.html et partiels qui étendent la disposition principale sous la partiels dossier. controllers.js est pour définir nos actions de contrôleur dans le front-end. services.js est pour faire des demandes de service à notre service que j'ai mentionné dans le projet précédent. Nous avons un fichier de type bootstrap appelé app.js et dans ce fichier, les configurations et les importations de modules sont appliquées. finalement, client.js sert à servir des fichiers HTML statiques (ou simplement index.html, dans ce cas); cela nous aide à servir des fichiers HTML statiques lorsque vous effectuez un déploiement sur un serveur sans utiliser Apache ni aucun autre serveur Web..

         

Dans le fichier HTML de présentation principal, tous les fichiers JavaScript requis sont inclus pour les bibliothèques liées à AngularJS, ainsi que notre contrôleur personnalisé, notre service et notre fichier d'application..

'use strict'; / * Contrôleurs * / angular.module ('angularRestfulAuth') .controller ('HomeCtrl', ['$ rootScope', '$ scope', '$ location', '$ localStorage', 'principal', fonction ($ rootScope, $ scope, $ location, $ localStorage, Main) $ scope.signin = function () var formData = email: $ scope.email, mot de passe: $ scope.password Main.signin (formData, function (res)  if (res.type == false) alert (res.data) else $ localStorage.token = res.data.token; window.location = "/";, fonction () $ rootScope.error = 'Échec de la connexion';); $ scope.signup = fonction () var formData = email: $ scope.email, mot de passe: $ scope.password Main.save (formData, function (res) if ( res.type == false) alert (res.data) else $ localStorage.token = res.data.token; window.location = "/", function () $ rootScope.error = 'Echec de signup ';); $ scope.me = function () Main.me (function (res) $ scope.myDetails = res;, function () $ rootScope.error =' Impossible de récupérer les détails '; ); $ scope.logout = function () Main.logout (fu nction () window.location = "/", function () alert ("Impossible de se déconnecter!"); ); ; $ scope.token = $ localStorage.token; ])

Dans le code ci-dessus, le HomeCtrl le contrôleur est défini et certains modules requis sont injectés comme $ rootScope et $ scope. L’injection de dépendance est l’une des propriétés les plus puissantes d’AngularJS. $ scope est la variable de pont entre les contrôleurs et les vues dans AngularJS, ce qui signifie que vous pouvez utiliser tester en vue si vous avez défini dans un contrôleur spécifié comme $ scope.test =…  

Dans ce contrôleur, certaines fonctions utilitaires sont définies, telles que:

  • se connecter configurer un bouton de connexion sur le formulaire de connexion
  • s'inscrire pour la gestion des formulaires d'inscription
  • moi pour assigner le bouton Moi dans la mise en page

Dans la présentation principale, dans la liste du menu principal, vous pouvez voir le contrôleur de données attribut avec une valeur HomeCtrl. Cela signifie que ce menu dom l'élément peut partager la portée avec HomeCtrl. Lorsque vous cliquez sur le bouton d’inscription du formulaire, la fonction d’inscription du fichier du contrôleur est exécutée. Dans cette fonction, le service d’inscription est utilisé à partir du Principale service déjà injecté dans ce contrôleur. 

La structure principale est vue -> contrôleur -> service. Ce service envoie de simples requêtes Ajax au back-end afin d'obtenir des données spécifiques.

'use strict'; angular.module ('angularRestfulAuth') .factory ('Main', ['$ http', '$ localStorage', fonction ($ http, $ localStorage) var baseUrl = "votre_service_url"; fonction changeUser (utilisateur) angulaire. extend (currentUser, user); function urlBase64Decode (str) var output = str.replace ('-', '+'). replace ('_', '/'); commutateur (output.length% 4)  cas 0: casse; cas 2: sortie + = '=='; casse 3: sortie + = '='; casse; défaut: lance 'Chaîne illégale base64url!'; retour window.atob (sortie); function getUserFromToken () jeton var = $ localStorage.token; var utilisateur = ; if (type jeton! == 'undefined') var encodé = token.split ('.') [1]; utilisateur = JSON. parse (urlBase64Decode (encoded)); utilisateur de retour; var currentUser = getUserFromToken (); return save: function (données, succès, erreur) $ http.post (baseUrl + '/ signin', data) .success ( succès) .error (erreur), connexion: fonction (données, réussite, erreur) $ http.post (baseUrl + '/ authenticate', données) .success (succès) .error (erreur), me: fonction ( succès, erreur) $ htt p.get (baseUrl + '/me').success(success).error(error), déconnectez-vous: function (success) changeUser (); delete $ localStorage.token; Succès(); ; ]);

Dans le code ci-dessus, vous pouvez voir les fonctions de service telles que les requêtes d’authentification. Dans controller.js, vous avez peut-être déjà compris qu'il existe des fonctions telles que Main.me. Ce Principale un service a été injecté dans le contrôleur et dans le contrôleur, les services appartenant à ce service sont appelés directement. 

Ces fonctions sont simplement des requêtes Ajax à notre service que nous avons déployées ensemble. N'oubliez pas de mettre l'URL du service dans baseUrl dans le code ci-dessus. Lorsque vous déployez votre service sur Heroku, vous obtenez une URL de service telle que appname.herokuapp.com. Dans le code ci-dessus, vous définissez var baseUrl = "appname.herokuapp.com"

Dans la partie inscription ou connexion de l'application, le jeton de support répond à la demande et ce jeton est enregistré dans la mémoire de stockage locale. Chaque fois que vous faites une demande à un service dans le back-end, vous devez mettre ce jeton dans les en-têtes. Vous pouvez le faire en utilisant des intercepteurs AngularJS.

$ httpProvider.interceptors.push (['$ q', '$ emplacement', '$ localStorage', fonction ($ q, $ emplacement, $ localStorage) retour 'demande': fonction (config) config.headers = config.headers || ; if ($ localStorage.token) config.headers.Authorization = 'Bearer' + $ localStorage.token; retour config;, 'responseError': fonction (réponse) if (réponse. status === 401 || response.status === 403) $ location.path ('/ signature'); return $ q.reject (réponse);;]);

Dans le code ci-dessus, chaque demande est interceptée et un en-tête d'autorisation et une valeur sont placés dans les en-têtes..

Dans le projet frontal, nous avons quelques pages partielles comme se connecters'inscrireDétails du profil, et vb. Ces pages partielles sont liées à des contrôleurs spécifiques. Vous pouvez voir cette relation dans app.js:

angular.module ('angularRestfulAuth', ['ngStorage', 'ngRoute']) .config (['$ routeProvider', '$ httpProvider', fonction ($ routeProvider, $ httpProvider) $ routeProvider. lorsque ('/', templateUrl: 'partials / home.html', contrôleur: 'HomeCtrl'). when ('/ signature', templateUrl: 'partials / signin.html', contrôleur: 'HomeCtrl'). when ('/ signup ', templateUrl:' partials / signup.html ', contrôleur:' HomeCtrl '). when (' / me ', templateUrl:' partials / me.html ', contrôleur:' HomeCtrl '). sinon ( rediriger vers: '/' );

Comme vous pouvez facilement le comprendre dans le code ci-dessus, lorsque vous accédez à /, la home.html la page sera rendue. Un autre exemple: si vous allez à /s'inscriresignup.html sera rendu. Cette opération de rendu se fera dans le navigateur, pas sur le serveur..

Conclusion

Vous pouvez voir comment tout ce que nous avons discuté dans ce tutoriel fonctionne dans la pratique en consultant cette démo qui fonctionne..

Les systèmes d'authentification basés sur des jetons vous aident à créer un système d'authentification / autorisation pendant que vous développez des services indépendants du client. En utilisant cette technologie, vous vous concentrez uniquement sur vos services (ou API). 

La partie authentification / autorisation sera gérée par le système d'authentification basé sur des jetons en tant que couche devant vos services. Vous pouvez accéder aux services et les utiliser à partir de n'importe quel client, tels que les navigateurs Web, Android, iOS ou un client de bureau..

Et si vous recherchez des solutions toutes faites, consultez les scripts et les applications d'authentification sur Envato Market..