Construisez votre premier routeur dans le nœud avec Express –
Cet article a été publié à l'origine sur sur le blog des développeurs d'Okta . Merci de votre soutien aux partenaires qui rendent SitePoint possible.
Si vous avez réalisé un développement Web avec Node au cours des dernières années, vous avez probablement utilisé Express. Même si vous ne l'avez pas utilisé directement, de nombreux frameworks destinés à simplifier encore le développement Web sont toujours basés sur Express.
L'une des fonctionnalités clés d'Express est la possibilité de créer des itinéraires. Une combinaison infinie d'URL peut atteindre le même serveur Express, et les itinéraires vous permettent de déterminer quelles URL exécutent quel morceau de code. Vous pouvez avoir des paramètres et des caractères génériques pour ne pas avoir à déclarer explicitement chaque extrémité.
Dans ce didacticiel, je vais vous expliquer comment créer un serveur et vous apprendre tout ce que vous devez savoir sur les itinéraires dans Express. [19659005] Qu'est-ce qu'une route dans Express?
Les routes déterminent quelles données doivent être fournies avec une adresse URL quelconque. Prenons comme exemple le serveur de fichiers le plus élémentaire. Supposons que vous ayez une structure de fichier de:
files /
├── images /
│ ├── cat.png
├── ├── dog.jpg
└── └── pig.bmp
└── texte /
├── LISEZMOI.md
└── todo.txt
Vous pourriez alors exécuter un serveur HTTP simple qui servira automatiquement ces fichiers et créera un index pour les répertoires. Il n’ya pas de fichiers / index.html
mais le serveur génère toujours une page Web et diffuse du contenu en fonction des fichiers de ce dossier. Si vous allez dans /images/cow.gif
vous obtiendrez une erreur 404 – même s'il n'y a pas de fichier, il sert toujours quelque chose .
npm install -g serveur http
fichiers cd
serveur http
Dans Express, un itinéraire consiste en une méthode
un chemin
et un de gestionnaire
.
Méthodes, chemins et gestionnaires, Oh My!
La méthode
peut être n’importe quel verbe HTTP, tel que GET
(pour récupérer du contenu – c’est ce que la plupart des pages Web utiliser) ou POST
(pour envoyer du contenu au serveur – ceci est courant avec les formulaires HTML). Si vous le souhaitez, vous pouvez également indiquer que vous souhaitez que Express gère le même chemin pour toutes les méthodes.
Le chemin
est une chaîne ou une expression régulière décrivant l'URL relative. Si vous travaillez avec la racine de votre application, cela décrit l’URL absolue. Un chemin peut être défini de plusieurs manières.
- Chaînes simples : Une chaîne de
'/'
indique que vous souhaitez utiliser cette route à la racine de votre routeur. Une chaîne de'/ asdf'
couvrirait le chemin/ asdf
- Caractères génériques : La chaîne peut également contenir quelques caractères génériques, qui ressemblent à une expression régulière, mais sont un peu limité:
?
: Un?
dit que le caractère précédent est facultatif. Le chemin'/ Joh? N'
couvrirait à la fois/ Jon
et/ John
+
: A+
indique que le le caractère précédent peut être répété autant de fois que vous le souhaitez, mais doit l'être au moins une fois. Un chemin de'/ ni + ce'
couvrirait/ nice
ainsi que/ niiiiiiiiiiiiiiiiice
*
: A*
dit le caractère précédent est facultatif et peut être répété autant de fois que vous le souhaitez. Un chemin de'/ wow! *'
correspondrait à/ wow
/ wow!
ou même/ wow !!!!!!! !!!!!
()
: Vous pouvez également appliquer des caractères génériques à un groupe de caractères.'/ (ha) +'
correspondrait à/ ha
/ haha
et/ hahahahaha
mais pas/ hah
- Expressions régulières : Si vous souhaitez aller au-delà des caractères génériques de base, vous pouvez utiliser des expressions régulières. Avec
/ ^ / (stylo -)? ((Pin)? Pomme -) + stylo $ /
vous pouvez faire correspondre/ stylo-pomme
/ stylo-ananas
ou/ stylo-ananas-pomme-stylo
. - Paramètres : Une autre fonctionnalité très utile est la possibilité d'avoir des paramètres sur votre itinéraire. Cela vous permet de fournir facilement des URL RESTful avec des portions dynamiques. Un chemin de
'/ posts /: postId'
correspond non seulement à/ posts / 42
mais la demande contient une variableparams.postId
avec une valeur de'42'
.
La méthode et le chemin sont essentiels pour savoir quand faire quelque chose, mais le gestionnaire est la fonction de rappel qui est appelée dans ces cas. Un gestionnaire reçoit une demande
une réponse
et un rappel next
et ces arguments sont généralement écrits sous la forme (req, res, next)
..
- Requête (
req
) : La requête contient toutes sortes d'informations sur les informations demandées par l'utilisateur. À partir de là, vous pouvez accéder au chemin, aux paramètres, aux en-têtes et à une multitude d'autres choses. Pour tout ce qui concerne une demande, vous pouvez consulter la référence API - Réponse (
res
) : La réponse est la façon dont vous renvoyez des informations à l'utilisateur. Le moyen le plus simple de renvoyer des données est la méthode.send
(par exempleres.send ('Hello, world!')
), mais il existe de nombreuses autres méthodes. Encore une fois, vous pouvez trouver toutes les méthodes dans la référence API - Prochain rappel (
suivant
) : La fonctionsuivante
vous permet d’utiliser plusieurs manutentionnaires pour le même itinéraire. Vous pouvez utiliser un gestionnaire pour traiter les informations. Une fois terminé, il peut appelernext ()
pour indiquer que vous pouvez passer au gestionnaire suivant. Si vous transmettez une chaîne, une erreur que vous pouvez localiser ailleurs ou afficher à l'utilisateur est renvoyée (par exemple,next ("Vous devez être authentifié pour accéder à cette route")
). [19659027] Qu'est-ce qu'un routeur dans Express?Maintenant que vous êtes un peu plus familiarisé avec les itinéraires, en quoi cela diffère-t-il d'un routeur? Vous pouvez considérer un routeur comme un ensemble de routes. Cela peut être un moyen utile d’organiser différentes sections de votre application.
Lorsque vous utilisez un routeur, vous pouvez penser en termes de chemin racine, même si vous allez utiliser ce routeur à partir d’un sous-chemin. Par exemple, supposons que vous ayez une API pour gérer les messages. Vous pouvez avoir un routeur avec un chemin
'/'
versGET
tous les messages ou unPOST
un nouveau message. Vous pourriez avoir un autre chemin'/: id'
versGET
ouPUT
(modifier) un message spécifique.Votre application pourrait alors prendre ce routeur et hébergez-le à
/ messages
avecapp.use ('/ messages', messageRouter)
. Le routeur lui-même n'a pas à se soucier de son chemin global et peut même être utilisé dans plusieurs routes (par exemple,/ messages
/ textes
et. /email
).Créez une application simple avec un routeur dans un nœud avec Express
Assez parlé déjà… passons à un code réel. Pour commencer, créez un dossier qui contiendra tout votre code. Configurez ensuite un dossier
package.json
pour faciliter la gestion des dépendances. Vous pouvez utilisernpm init
pour ce faire. Vous devez également installer Express .mkdir mon-premier-routeur. cd mon-premier-routeur npm init -y npm install express@4.16.4 hbs@4.0.1
Créez un fichier
index.js
avec le code suivant:index.js
const express = require ('express') const path = require ('path') const app = express () app.set ('vues', chemin.join (__ nom de répertoire, 'vues')) app.set ('moteur de visualisation', 'hbs') app.get ('/', (req, res) => { res.render ('index', { titre: 'Bonjour tout le monde!', contenu: 'comment ça va?' }) }) const port = process.env.PORT || 3000 app.listen (port, () => console.log (`App qui écoute sur le port $ {port}`))
Cela indique à Express d'utiliser le Guidon (
hbs
) comme moteur de visualisation. Il utilise le cheminintégré
de Node pour lui indiquer le répertoire contenant les vues. Le chemin/
indique de rendre la page à l'aide deindex.hbs
ce qui mettra le contenup
) .Pour vous assurer qu'Express dispose des modèles à restituer, créez un nouveau dossier appelé
views
puis créez un nouveau fichier appelélayout.hbs
. Lorsque vous indiquez à Express de rendre une vue, il convertit d'abordlayout.hbs
et place le contenu de la vue dans la balise{{{body}}}
. Cela vous permet de configurer un squelette pour l'application. Voici du code HTML de base utilisant Bootstrap qui vous donnera un style agréable sans avoir à écrire de code CSS. Cela rendra également le titre/
.views / layout.hbs
{{title}} { {title}}
{{{body}}} Vous aurez également besoin de créer une vue
index.hbs
qui sera simplement fondamentale pour l'instant:views / index.hbs
{{content}}
Pour faciliter le développement, vous pouvez installer
nodemon
avec:npm install --save-dev nodemon@1.18.4
Modifiez ensuite votre fichier
package.json
afin que l'entrée"scripts"
inclue un script de début avecnodemon.
. Ainsi, vous pourrez simplement exécuternpm start
et votre serveur redémarrera automatiquement à chaque modification:"scripts": { "start": "nodemon". }
Maintenant, dans votre terminal, si vous tapez
npm start
vous démarrez le serveur. Vous pouvez ensuite aller àhttp: // localhost: 3000
pour voir l'application en cours d'exécution.Créer un routeur dans Express
Eh bien, c'est ennuyeux . Pourquoi ne pas faire quelque chose d'utile? Créons une simple liste de choses à faire. Commencez par créer un routeur pour gérer une liste d'éléments. Créez un nouveau fichier appelé
todo.js
:todo.js
const express = require ('express') routeur const = express.Router () let todo = [] router.post ('/', (req, res, next) => { todo = [reqbodytodo||[]] if (req.body.remove) todo.splice (req.body.remove, 1) if (req.body.new) todo.push ({}) suivant() }) router.use ('/', (req, res) => { res.render ('todo', {titre: 'liste de tâches', todo}) }) module.exports = routeur
Vous avez ici deux gestionnaires d'itinéraire. Le premier écoute les demandes
POST
(signifiées parrouter.post
). Il remplacera la liste de tâches par une copie de tout ce qu'il reçoit du formulaire. Si le formulaire contient la propriétéremove
(contenant un index), il utiliseral'épissure
pour supprimer l'élément situé à cet index. Si le formulaire contient la propriéténew
un nouvel élément sera placé dans le tableau. Après avoir modifié la liste des tâches, il appellenext ()
pour passer au prochain gestionnaire d'itinéraire.Le deuxième gestionnaire d'itinéraire est toujours utilisé (indiqué par
routeur.use [
). Son seul objectif est de rendre la liste des tâches à effectuer. En séparant les itinéraires de cette manière, vous pouvez toujours faire une chose, et une autre chose seulement dans certaines circonstances (dans ce cas, sur une demandePOST
).Indiquer à l'application d'utiliser ce routeur, vous devrez ajouter quelques lignes à
index.js
:index.js
@@ -1,11 +1,15 @@ const express = require ('express') const path = require ('path') + const todoRouter = require ('./ todo') const app = express () app.set ('vues', chemin.join (__ nom de répertoire, 'vues')) app.set ('moteur de visualisation', 'hbs') + app.use (express.urlencoded ({extended: true})) + app.use ('/ todo', todoRouter) + app.get ('/', (req, res) => { res.render ('index', { titre: 'Bonjour tout le monde!',
Passons maintenant au modèle
todo
. C’est un peu plus grand, alors je l’ai gardé pour la fin. Si vous connaissez le HTML, il ne devrait pas être trop mauvais à suivre. Handlebars ajoute quelques fonctionnalités qui vous permettent d’accéder aux variables. Dans ce cas, vous utilisez un bloc{{# if}}
pour rendre quelque chose de spécial s'il n'y a pas d'éléments, ainsi qu'un{{# each}}
bloquer le rendu de chacun des éléments de la liste avec un minimum de balises.Le seul JavaScript utilisé ici sert à soumettre automatiquement le formulaire lorsque vous modifiez quelque chose. Si JavaScript était désactivé, cela fonctionnerait quand vous appuieriez sur la touche "Entrée" de votre clavier, grâce au bouton caché intitulé "Sauvegarde automatique".
views / todo.hbs
Allez maintenant à
http: // localhost: 3000 / todo
et entrez des éléments dans votre liste de tâches.Ajoutez l'authentification de l'utilisateur au nœud
Maintenant vous avez une liste de tâches fonctionnelle. Vous avez peut-être remarqué que cela ne fonctionnerait que si vous voulez que tous les utilisateurs partagent la même liste. Si vous ajoutez une authentification, vous pouvez avoir une liste de tâches distincte pour chaque utilisateur.
L'ajout d'utilisateurs ne doit pas être une tâche ardue. En fait, cela peut être fait très simplement avec Okta. Qu'est-ce qu'Okta? pourriez-vous demander. Okta est un service cloud qui permet aux développeurs de créer, éditer et stocker de manière sécurisée les comptes d'utilisateurs et leurs données, et de les connecter à une ou plusieurs applications.
Si vous n'en avez pas encore, inscrivez-vous à un compte de développeur gratuit pour toujours .
Vous allez avoir besoin d'enregistrer des informations à utiliser dans l'application. Créez un nouveau fichier nommé
.env
. Entrez-y l'URL de votre organisation.HOST_URL = http: // localhost: 3000 OKTA_ORG_URL = https: // {votreOktaOrgUrl}
Vous aurez également besoin d'une chaîne aléatoire à utiliser comme secret d'application pour les sessions. Vous pouvez générer cela avec les commandes suivantes:
echo -e " nAPP_SECRET =` npx -q uuid` ">> .env
Ensuite, connectez-vous à votre console de développeur, accédez à Applications puis cliquez sur Ajouter une application . Sélectionnez Web puis cliquez sur Suivant . Donnez à votre application un nom, par exemple «Mon premier routeur». Remplacez l'URI de base par
http: // localhost: 3000 /
et par l'URI de redirection de connexion parhttp: // localhost: 3000 / autorisation- code / rappel
puis cliquez sur TerminéCliquez sur Modifier et ajoutez un URI de redirection de
http: // localhost: 3000 /
puis cliquez sur Sauvegardez .La page que vous consultez après la création d'une application contient des informations supplémentaires que vous devez sauvegarder dans votre
.env
fichier. Copiez l'ID client et le secret client.OKTA_CLIENT_ID = {yourClientId} OKTA_CLIENT_SECRET = {votreClientSecret}
Revenons maintenant au code. Vous devez ajouter le middleware OIDC d’Okta pour contrôler l’authentification. Il repose également sur l'utilisation de sessions. Vous devez utiliser
dotenv
pour lire les variables du fichier.env
. Pour installer les dépendances dont vous aurez besoin, exécutez la commande suivante:npm install @ okta / oidc-middleware @ 1.0.1 dotenv@6.1.0 express-session@1.15.6
Modifiez maintenant votre fichier
index.js
. Vous allez ajouter ici les middlewares de session et OIDC, ainsi qu'un itinérairede déconnexion
afin que les utilisateurs puissent se déconnecter de l'application. Vous ajoutez également un middleware spécifiquement à la commandetodoRouter
(app.use ('/ todo', oidc.ensureAuthenticated (), todoRouter)
). En ajoutantoidc.ensureAuthenticated ()
vous permettez à Okta de s'assurer que cet itinéraire ne peut être atteint que si un utilisateur est connecté. Si l'utilisateur n'est pas connecté et tente d'atteindre cet itinéraire, ils seront redirigés vers un site sécurisé, puis redirigés vers votre site.index.js
@@ -1,14 +1,46 @@ + require ('dotenv'). config () + const express = require ('express') const path = require ('path') + const session = require ('express-session') + const {ExpressOIDC} = require ('@ okta / oidc-middleware') + const todoRouter = require ('./ todo') + const oidc = new ExpressOIDC ({ + issuer: `$ {process.env.OKTA_ORG_URL} / oauth2 / default`, + client_id: process.env.OKTA_CLIENT_ID, + client_secret: process.env.OKTA_CLIENT_SECRET, + redirect_uri: `$ {process.env.HOST_URL} / code d'autorisation / callback`, + scope: 'profil ouvert' +}) + const app = express () + app.use (session ({ + secret: process.env.APP_SECRET, + resave: true, + saveUninitialized: false +})) + app.use (oidc.router) + app.set ('vues', chemin.join (__ nom de répertoire, 'vues')) app.set ('moteur de visualisation', 'hbs') app.use (express.urlencoded ({extended: true})) -app.use ('/ todo', todoRouter) + app.use ('/ todo', oidc.ensureAuthenticated (), todoRouter) + + app.get ('/ logout', (req, res) => { + if (req.userContext) { + const idToken = req.userContext.tokens.id_token + const to = encodeURI (process.env.HOST_URL) + const params = `id_token_hint = $ {idToken} & post_logout_redirect_uri = $ {to}` + req.logout () + res.redirect (`$ {process.env.OKTA_ORG_URL} / oauth2 / default / v1 / logout? $ {params}`) +} else { + res.redirect ('/') +} +}) app.get ('/', (req, res) => { res.render ('index', {
Pour faciliter la tâche lorsqu'un utilisateur se déconnecte, ajoutez un lien vers la liste des tâches de la page d'accueil.
views / index.hbs
{{content}} [19659093] Aller à la liste des tâches
Vous pouvez également ajouter un message de bienvenue et un bouton de déconnexion à votre
layout.hbs
.views / layout.hbs
@@ -12,6 +12, 12 @@
{{title}}
+ {{#if userinfo}} ++ Bienvenue, {{userinfo.given_name}}! + Cliquez ici pour vous déconnecter +
+ {{/ if}}{{{corps}}} Pour que cela fonctionne, vous devez ajouter
userinfo
au contexte lors du rendu des vues.todo.js
--- a / todo.js +++ b / todo.js @@ -13,7 +13,7 @@ router.post ('/', (req, res, next) => { }) router.use ('/', (req, res) => { - res.render ('todo', {titre: 'liste de tâches', todo}) + res.render ('todo', {titre: 'liste de choses à faire', todo, userinfo: req.userContext.userinfo}) }) module.exports = routeur
index.js
@@ -43,7 +43,10 @@ app.get ('/ logout', (req, res) => { }) app.get ('/', (req, res) => { + const {userinfo} = req.userContext || {} + res.render ('index', { + userinfo, titre: 'Bonjour tout le monde!', contenu: 'comment ça va?' })
OK, vous demandez donc aux utilisateurs de se connecter avant de pouvoir modifier la liste des tâches, mais cette liste est toujours unique. Pour le scinder en une liste distincte pour chaque utilisateur, apportez un autre petit changement à
todo.js
.todo.js
@@ -2,17 +2, 21 @@ const express = require ('express') routeur const = express.Router () -let todo = [] + const todosByUser = {} router.post ('/', (req, res, next) => { - todo = [reqbodytodo||[]] + const todo = [reqbodytodo||[]] if (req.body.remove) todo.splice (req.body.remove, 1) if (req.body.new) todo.push ({}) + todosByUser [req.userContext.userinfo.sub] = todo + suivant() }) router.use ('/', (req, res) => { + const todo = todosByUser [req.userContext.userinfo.sub] || [] + res.render ('todo', {titre: 'liste de tâches', tâches, userinfo: req.userContext.userinfo}) })
En savoir plus sur les développements de nœud, express et sécurisé Web
Maintenant que vous disposez d'une liste de tâches entièrement fonctionnelle, je vous encourage à la développer davantage. Essayez de stocker les données dans une base de données, ou même laissez Okta les stocker pour vous ! Voyez si vous pouvez créer d'autres routeurs à ajouter au serveur Web.
Si vous souhaitez voir le dernier exemple de code, vous pouvez le trouver sur GitHub .
Si vous le souhaitez Pour en savoir plus sur Node and Express, consultez ces articles sur le blog des développeurs d’Okta:
Si vous avez des questions concernant cette publication, veuillez ajouter un commentaire ci-dessous. Pour un contenu plus génial, suivez @oktadev sur Twitter, comme nous sur Facebook ou abonnez-vous à sur notre chaîne YouTube .
Source link