Fermer

juillet 10, 2018

Comment ajouter Auth à votre PWA avec Okta et Stencil –


Cet article a été publié à l'origine le Okta Developer Blog . Nous vous remercions de soutenir les partenaires qui rendent SitePoint possible.

Les applications Web progressives (PWA) sont la technologie la plus récente du bloc de développement Web et sont arrivées juste à temps pour résoudre un problème croissant. De nombreuses entreprises s'efforcent de maintenir à jour les équipes de développement isolées de leur organisation lorsque de nouvelles fonctionnalités sont publiées. Certaines entreprises essaient même de décider si cela vaut la peine de développer à la fois une application web et une application mobile. Sans surprise, c'est un mal de tête que la plupart des entreprises cherchent à éviter. Les PWA peuvent fournir aux entreprises un grand nombre de fonctionnalités dont elles ont besoin depuis une application mobile sans devoir gérer plusieurs équipes et bases de code. Un PWA fonctionne de façon spectaculaire avec une connexion rapide. ou sur Wi-Fi, ce n'est pas vraiment assez rapide pour être appelé Wi-Fi (parfois appelé "Lie-Fi"). Il le fait via la mise en cache et un "Service Worker" JavaScript qui intercepte les appels serveur et essaie d'abord de servir les données du cache, puis quand le serveur répondra, il remplacera les données mises en cache par des données "plus récentes" du serveur. 19659003] Récemment, l'équipe Ionic a publié un nouveau projet appelé Stencil . Stencil est un compilateur qui génère des composants Web conformes aux normes. Contrairement à la plupart des frameworks JavaScript, il ne fournit pas de "framework" de code au navigateur. Il prend simplement le code que vous écrivez et utilise son compilateur pour créer des composants vanilla. Vous pouvez également utiliser le compilateur de Stencil avec votre framework préféré. Le projet Stencil starter est le moyen le plus facile de démarrer avec Stencil et produit une application de base qui obtient un score de près de 100% sur le tableau de bord de l'application progressive du Lighthouse . commencez à construire un PWA en utilisant Stencil, clonez l'application de démarrage et détachez-le de la télécommande GitHub

AVERTISSEMENT : Le Stencil n'est pas encore en version 1.0 (à ce jour). Sachez donc que si vous continuez, vous êtes dans le territoire des premiers utilisateurs. Si vous trouvez des bugs, soumettez un problème .

Configurer l'application de démarrage

 git clone https://github.com/ionic-team/stencil-starter.git Premier pochoir
premier pochoir cd
git remote rm origine

Ensuite, installez toutes les dépendances dont votre nouvelle application Stencil aura besoin.

 npm install

Vous pouvez voir quelques avertissements de node-pre-gyp autour de fsevents . Il n'y a rien à voir ici. Ceci est juste pour contourner un [ndt: méchant petit bug npm .

Ensuite, ajoutez le Okta Auth SDK (via CDN) au bas de la page index.html juste avant l'étiquette de fermeture.

   

Bien qu'il existe un paquet npm pour le SDK Auth d'Okta, Stencil a du mal à le compiler. Globalement, cela fonctionne mieux pour l'instant si vous utilisez simplement le CDN pour l'inclure.

Si vous êtes comme moi, la prochaine chose que vous voulez faire est de lancer npm start et de vérifier le site avec Phare. Si vous le faites, vous remarquerez que le score est genre de faible. En particulier, il n'enregistre pas un agent de service ou renvoie un 200 en mode hors connexion. C'est parce que c'est un développement de et généralement, vous ne voulez pas que le technicien intercepte les appels de serveur et renvoie les données mises en cache en développement.

Pour assurer une description précise du type de PWA vous sortez de la boîte avec Stencil, assurez-vous de lancer une compilation production en utilisant npm run build . Une fois cela fait, vous verrez un dossier www et dans ce dossier, vous verrez un fichier sw.js .

Configurer votre application Okta

Si vous ne l'avez pas déjà fait, créez un compte de développeur gratuit pour toujours .

Une fois inscrit, cliquez sur Applications dans le menu supérieur. Puis cliquez sur Ajouter une application .

 Écran Liste des applications

Vous serez ensuite redirigé vers l'assistant de création d'application. Choisissez l'appli Single-Page et cliquez sur Suivant en bas

 Créer l'écran d'application SPA

Sur l'écran suivant, vous verrez le paramètres par défaut fournis par le modèle d'application à une seule page. Changez le nom de l'application en quelque chose de plus descriptif, comme "Stencil SPA". En outre, modifiez les URI de base et les paramètres URI de redirection de connexion pour utiliser le port 3333 car c'est là que votre application sera exécutée. Les autres paramètres par défaut sont corrects

 Écran Paramètres de l'application

Cliquez sur Terminé en bas

Sélectionnez votre application nouvellement créée dans la liste, puis cliquez sur sur l'onglet Général pour afficher les paramètres généraux

 Paramètres généraux ID client

En bas, vous verrez un paramètre ID client (le vôtre ne sera pas brouillé, évidemment). Copiez ceci pour l'utiliser dans votre application Stencil. Vous aurez également besoin de votre URL d'organisation Okta, que vous pouvez trouver en haut à droite de la page du tableau de bord. Cela ressemblera probablement à quelque chose comme "https://dev-XXXXXX.oktapreview.com".

Ajouter le composant d'authentification

Dans le dossier components ajouter un nouveau dossier appelé app -auth . C'est ici que votre composant de page de connexion ira. Vous pouvez l'appeler comme vous voulez, je suis juste en suivant les conventions de nommage énoncées par l'application de démarrage ici. Je recommande vivement de choisir une convention de nommage de manière anticipée et de la respecter

Dans le dossier app-auth nouvellement créé, créez deux fichiers: app-auth.css et app-auth.tsx . Commencez par créer le shell du fichier app-auth.tsx .

 import {Component} de '@ stencil / core';

@Composant({
  tag: 'app-auth',
  styleUrl: 'app-auth.css'
})
classe d'exportation AppAuth {
  render () {
    retour 
Bonjour
;   } }

Si vous êtes comme je l'étais, vous pourriez penser: "Quel genre de cadre Frankenstein est-ce?"

Vous remarquerez le décorateur @Component sur le AppAuth ] déclaration de classe comme Angular, puis une méthode render () en bas comme React. Pour moi, c'est la beauté de Stencil. Il prend certaines des meilleures parties des deux cadres populaires et les utilise pour compiler des composants réutilisables!

Ajouter un formulaire de connexion

Ensuite, vous ajouterez le JSX (c'est exact, je l'ai dit) au nouveau composant. Remplacez la méthode render () par:

 render () {
  revenir (
    
); }

Ceci est juste un formulaire JSX normal, mais l'événement onClick du bouton de connexion est actuellement connecté à une fonction qui n'existe pas

Ajouter les dépendances de la méthode de connexion

Avant de créer cette fonction , vous devrez configurer l'objet JavaScript OktaAuth pour appeler l'API Okta pour l'authentification. Vous allez ajouter l'objet à l'état du composant, donc juste en dessous de la déclaration de la classe, ajoutez la ligne suivante:

 @State () authClient: any;

Vous devrez également importer le décorateur @State () . Ceci est utilisé pour les valeurs liées à l'état interne du composant. Dans la première déclaration import ajoutez l'état à la liste de déconstruction.

 import {Component, State} à partir de '@ stencil / core'

Vous devrez également récupérer les valeurs du nom d'utilisateur et du mot de passe à partir du formulaire, ajoutez @Element () au code juste en dessous de @State () comme vous venez de créer, donc il se lit comme ceci:

 @State () authClient: any;
Hôte @Element (): HTMLElement;

Ajoutez ensuite le décorateur @Element () à l'importation pour qu'il indique:

 import {Component, State, Element} à partir de '@ stencil / core';

Une dernière chose dont la fonction login () aura besoin est l'accès au routeur, donc vous pouvez rediriger l'utilisateur vers sa page de profil si son authentification est réussie. Vous aurez besoin d'une propriété de classe, ajoutez-la donc juste en dessous du @Element .

 @State () authClient: any;
Hôte @Element (): HTMLElement;
@Prop () historique: RouterHistory;

Pour l'importer, ajoutez le décorateur @Prop () à l'importation principale, puis importez le RouterHistory de @ stencil / router juste en dessous du noyau. déclaration d'importation. Le décorateur @Prop est utilisé pour définir les propriétés qui peuvent être transmises à votre composant. Dans ce cas, ce n'est pas une valeur transmise, mais cela pourrait être le cas si nécessaire. Votre section d'importation finale devrait se lire comme suit:

 import {Component, Prop, State, Element, Listen} à partir de '@ stencil / core';
importer {RouterHistory} à partir de '@ stencil / router';

Enfin, pour utiliser la bibliothèque JavaScript OktaAuth que vous avez importée du CDN, ajoutez-y une déclaration juste en dessous des instructions import

 declare const OktaAuth: any;

Ajouter la méthode de connexion

Vous avez maintenant inclus tout ce dont vous avez besoin pour obtenir la fonction de connexion afin d'authentifier les utilisateurs avec votre organisation Okta. Tout d'abord, configurez l'objet OktaAuth dans le constructeur de la classe AppAuth . Juste en dessous de la propriété de l'objet RouterHistory ajoutez:

 constructor () {
  this.authClient = new OktaAuth ({
    clientId: '{votreClientId}',
    url: 'https: // {yourOktaDomain} .com',
    émetteur: 'default'
  });
}

Vous pouvez obtenir votre ID de client à partir de cette page de paramètres généraux de votre application Okta.

Vous aurez également besoin de votre URL Okta, dans le coin supérieur droit de la page Okta.

 Okta Dashboard Org Url

Maintenant, tout est configuré pour la fonction login () vous allez donc le créer ensuite. Juste au-dessus de la méthode render () ajoutez une fonction login () .

 login () {
  laissez input = this.host.querySelectorAll ('entrée');
  laissez user = {
    nom d'utilisateur: entrées [0] .value,
    mot de passe: entrées [1] .value
  }

  return this.authClient.signIn (utilisateur)
    .then (res => {
      if (res.status === 'SUCCESS') {
        retourner this.authClient.token
          .getWithoutPrompt ({
            responseType: 'id_token',
            étendues: ['openid', 'profile', 'email'],
            sessionToken: res.sessionToken,
            redirectUri: 'http: // localhost: 3333'
          })
          .then (jeton => {
            localStorage.setItem (
              'okta_id_token',
              JSON.stringify (jeton)
            )
            this.history.push ('/ profile', {});
          });
      } autre {
        throw `Impossible de gérer le code d'état $ {res.status }`;
      }
    })
    .fail (fonction (err) {
      console.error (err);
    });
}

Puisque c'est vraiment la "viande" du composant, je vais vous expliquer ce qui se passe ici.

La première chose est d'obtenir toutes les entrées dans l'élément du composant. . Un objet utilisateur est ensuite créé avec le nom d'utilisateur et le mot de passe à partir de leurs entrées respectives.

L'objet authClient est ensuite utilisé pour appeler la méthode signIn () avec l'objet utilisateur créé. Il renvoie une promesse, donc vous gérez la condition puis en obtenant la réponse et vérifiez si le statut de la réponse est un 200. Si c'est le cas, appelez le authClient.token méthode getWithoutPrompt () qui renvoie également une promesse. Il faut une propriété responseType définie sur id_token car c'est ce que vous voulez obtenir d'Okta. Vous avez également demandé trois portées qui vous donneront les données d'ouverture, de profil et d'e-mail associées à l'utilisateur nouvellement authentifié. La méthode nécessite le jeton de session renvoyé par la réponse de la méthode signIn () . Enfin, vous avez dit à la fonction de rappeler le redirectUri qui a été défini comme origine de redirection fiable dans Okta lorsque vous avez créé votre application.

Dans la condition puis de cette promesse, vous prenez le jeton d'identité reçu et le placez dans le stockage local en tant que okta_id_token . Si tout cela a fonctionné, l'utilisateur est redirigé vers la page de profil.

Si la réponse avait un statut autre que 200, elle renvoie simplement une erreur qui indique qu'elle ne peut pas gérer d'autres états. Enfin, la condition d'échec de l'appel de méthode signIn () enregistre simplement les erreurs sur la console

Simplify Login

Bien que cela fonctionne, il y a deux choses qui rendraient ce composant un peu plus agréable : être capable de taper enter pour se connecter au lieu de devoir cliquer sur le bouton de connexion, et même ne pas afficher le formulaire de connexion si la personne essaie d'aller à la page de connexion quand elle est déjà connectée.

Pour y parvenir, ajoutez une méthode pour amener l'utilisateur directement à la page de profil s'il est déjà connecté. Tout comme les composants React, les composants Stencil ont des méthodes de cycle de vie. Au lieu de componentWillMount () pour React, Stencil possède une méthode componentWillLoad () c'est ce que vous utiliserez ici.

 componentWillLoad () {
  let idToken = localStorage.getItem ('okta_id_token');
  if (idToken) {
    this.history.push ('/ profile', {});
  }
}

Tout simplement, tout ce que vous faites est de lire le jeton du stockage local. S'il existe, vous supposez qu'ils sont connectés et les redirigez vers la page de profil.

La dernière chose qui rendra ce formulaire de connexion plus facile à utiliser est d'ajouter la possibilité de soumettre le formulaire avec la touche Entrée. Stencil a quelques écouteurs intégrés pour les touches. Dans ce cas, utilisez l'écouteur 'keydown.enter'. Importez le décorateur @Listen () dans l'instruction d'importation top où vous avez importé Component .

 import {Composant, Prop, État, Élément, Listen} depuis '@ stencil / coeur';

Puis ajoutez un gestionnaire pour l'événement 'keydown.enter' juste en dessous de la fonction componentWillLoad () .

 @Listen ('keydown.enter')
handleEnter () {
  this.login ();
}

Mise à jour de la page de profil

Maintenant que vous avez une bonne page de connexion, mettez à jour la page de profil pour qu'elle affiche les revendications de l'utilisateur une fois qu'il est connecté.

les revendications de l'utilisateur dans. Créez donc un nouveau fichier dans le dossier app-profile appelé AppUser.tsx . Le contenu est simple mais long. J'ai simplement regardé toutes les revendications dans le jeton stockées dans localStorage et créé une interface qui correspondait. Ainsi, le fichier AppUser.tsx est le suivant:

 interface AppUser {
  sub: chaîne;
  nom: chaîne;
  locale: chaîne;
  email: chaîne;
  ver: nombre;
  iss: chaîne;
  aud: string;
  iat: nombre;
  exp: nombre;
  jti: string;
  amr: string [];
  idp: string;
  nonce: chaîne;
  pseudo: chaîne;
  preferred_username: chaîne;
  given_name: string;
  nom_famille: chaîne;
  zoneinfo: string;
  updated_at: numéro;
  email_verified: booléen;
  auth_time: nombre;
}

Une fois que vous avez un type à déclarer pour l'objet utilisateur de votre profil, mettez à jour le fichier app-profile.tsx .

Les importations en haut devraient ressembler à:

 import {Component, Prop, State} à partir de '@ stencil / core';
importer {RouterHistory} à partir de '@ stencil / router';

Supprimez la ligne @Prop () pour match et remplacez par:

 @Prop () history: RouterHistory;
Utilisateur @State (): AppUser;
@Prop ({context: 'isServer'}) isServer privé: booléen;

La propriété isServer est une propriété spéciale. Étant donné que Stencil prend en charge le préconfiguration et localStorage peut ne pas être disponible pendant le prerender, vous devez envelopper les appels localStorage dans un if (! IsServer) {} assurez-vous qu'il sera construit pour la production. Cela ne devrait pas l'empêcher de fonctionner, c'est juste un travail autour du processus de construction.

Pour la méthode componentWillLoad () il suffit de lire les informations utilisateur du 'okta_id_token' dans le stockage local:

 componentWillLoad () {
  if (! this.isServer) {
    let jeton = JSON.parse (localStorage.getItem ('okta_id_token'));
    if (jeton) {
      this.user = token.claims;
    } autre {
      this.history.push ('/ login', {});
    }
  }
}

Ce sera aussi votre protecteur pour la page de profil, il vérifie juste si le jeton existe. Si oui, il charge les revendications de celui-ci. Sinon, il redirige vers la page de connexion.

Pour la méthode render () modifiez-la pour afficher les revendications dans une liste.

 render () {
  if (this.user) {
  let keys = Object.keys (this.user);
  return 

Réclamations de l'utilisateur

    {keys.map (key =>
  • {key} : {this.user [key]}
  • )}       
;   } }

Il ne reste plus qu'à ajouter la méthode logout () . Cela supprimera simplement le jeton du stockage local et rechargera la page, ce qui forcera componentWillLoad () à rediriger l'utilisateur vers la page de connexion.

 logout () {
  if (! this.isServer) {
    localStorage.removeItem ('okta_id_token');
    location.reload ();
  }
}

Configurer l'itinéraire de connexion

Il ne reste plus qu'à ajouter l'itinéraire au composant de connexion à l'application afin que les utilisateurs puissent y accéder.

Dans les composants / my-app / my- Le fichier app.tsx ajoute l'itinéraire à l'intérieur du composant stencil-router de sorte que la section finale ressemble à ceci:

 
  
  
  

Vous devrez également mettre à jour l'itinéraire pour le lien sur la page d'accueil. Dans components / app-home / app-home.tsx mettez à jour l'URL de l'élément stencil-route-link pour qu'elle ne passe plus dans le paramètre url.

 
  

C'est tout! Vous devriez maintenant être en mesure d'exécuter l'application, cliquer sur la page de profil, être redirigé vers la page de connexion, et être redirigé vers la page de profil une fois connecté. La page de profil devrait afficher toutes vos réclamations après avoir authentifié.

Félicitations, vous avez maintenant un PWA avec authentification, prêt à partir à la conquête du monde!

Ajouter des styles

En tant que crédit supplémentaire, vous pouvez ajouter un style au formulaire de connexion et au profil page. Voici ma feuille de style pour la page de connexion qui se trouve dans app-auth.css :

 .app-auth {
  largeur: 30%;
  marge: 2rem auto;
}
.app-auth .form-item {
  rembourrage: .25rem;
}
étiquette .app-auth {
  largeur: 100%;
  taille de police: 1rem;
  couleur: # 999;
}

Entrée d'étiquette .app-auth {
  largeur: 97%;
  border-radius: .25rem;
  taille de police: 1.5rem;
}

.app-auth .form-actions {
  text-align: droit;
}

Enfin, dans app-profile.css juste quelques styles simples pour mettre en gras l'étiquette de chaque élément.

 .app-profile {
  rembourrage: 10px;
}

.app-profile ul li span {
  font-weight: gras;
}

Maintenant, quand vous lancez l'application, vous verrez une application joliment stylée, prête pour le web!

 Stencil App Login Page

En savoir plus

Pour en savoir plus sur les PWA, consultez Matt Le guide ultime de Raible sur les PWAs sur le blog du développeur Okta.

Si vous voulez en savoir plus sur les applications ioniques, consultez le post de blog de sur les applications ioniques . peut apprendre à construire une application CRUD de base avec VueJS de le message de Brandon Parise .

Enfin, ici vous pouvez voir comment configurer l'enregistrement des utilisateurs avec Node et React !

] Comme toujours, si vous avez des questions vous pouvez commenter ci-dessous ou me contacter sur Twitter @leebrandt et ne pas oublier de suivre @OktaDev pour un excellent contenu de nos communautés + tous les nouvelles sur la plate-forme de développeur d'Okta!






Source link